Google編程大賽解題一道

來源:互聯網
上載者:User

Google編程大賽的題目的確對演算法、思維能力是一個考驗,在一個小時內完成的確是有點難度。經過檢驗,才發現自己在這方面平時的確比較欠缺呀。這道題我可是做了近半天才作完整了,跑通了題目給出的所有case。
原題:
Problem Statement
You are given a String[] grid representing a rectangular grid of letters. You are also given a String find, a word you are to find within the grid. The starting point may be anywhere in the grid. The path may move up, down, left, right, or diagonally from one letter to the next, and may use letters in the grid more than once, but you may not stay on the same cell twice in a row (see example 6 for clarification).
You are to return an int indicating the number of ways find can be found within the grid. If the result is more than 1,000,000,000, return -1.
Definition
Class:
WordPath
Method:
countPaths
Parameters:
String[], String
Returns:
int
Method signature:
int countPaths(String[] grid, String find)
(be sure your method is public)

Constraints
-
grid will contain between 1 and 50 elements, inclusive.
-
Each element of grid will contain between 1 and 50 uppercase ('A'-'Z') letters, inclusive.
-
Each element of grid will contain the same number of characters.
-
find will contain between 1 and 50 uppercase ('A'-'Z') letters, inclusive.
Examples
0)

{"ABC",
 "FED",
 "GHI"}
"ABCDEFGHI"
Returns: 1
There is only one way to trace this path. Each letter is used exactly once.
1)

{"ABC",
 "FED",
 "GAI"}
"ABCDEA"
Returns: 2
Once we get to the 'E', we can choose one of two directions for the final 'A'.
2)

{"ABC",
 "DEF",
 "GHI"}
"ABCD"
Returns: 0
We can trace a path for "ABC", but there's no way to complete a path to the letter 'D'.
3)

{"AA",
 "AA"}
"AAAA"
Returns: 108
We can start from any of the four locations. From each location, we can then move in any of the three possible directions for our second letter, and again for the third and fourth letter. 4 * 3 * 3 * 3 = 108.
4)

{"ABABA",
 "BABAB",
 "ABABA",
 "BABAB",
 "ABABA"}
"ABABABBA"
Returns: 56448
There are a lot of ways to trace this path.
5)

{"AAAAA",
 "AAAAA",
 "AAAAA",
 "AAAAA",
 "AAAAA"}
"AAAAAAAAAAA"
Returns: -1
There are well over 1,000,000,000 paths that can be traced.
6)

{"AB",
 "CD"}
"AA"
Returns: 0
Since we can't stay on the same cell, we can't trace the path at all.
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

這道題大意是讓你在給定的一個String數組描述的字元矩陣中,尋找指定的一個字串描述的路徑的個數,矩陣中8個方向都可以移動,路徑中一個字元可以出現多次,但是不能在同一個位置重複多次。如果題目理解的不太清楚,看看題目提供的幾個case,應該就清楚了。
實現思路:估計我這是最笨的一個辦法了。先在矩陣中尋找到所有的路徑的首字元的座標位置,然後迴圈再每一個首字元位置開始尋找路徑,尋找使用一個findPpath的遞迴方法,在當前位置的上下左右等8個方向上尋找路徑中的下一個字元,任何的方向找到就繼續調用遞迴方法。當找到路徑的最後一個字元時,就計數一條路徑。估計也沒有描述清楚,看看代碼吧:

import java.util.ArrayList;
/**
 * author:zming
 * http://blog.jweb.cn
 */
public class WordPath {
 // 路徑計數
 private int count = 0;

 //
 char[][] grid2;

 /**
  * @param grid
  *            矩陣資料
  * @param find
  *            路徑串
  * @return 找到的路徑個數
  */
 public int countPaths(String[] grid, String find) {
  char first;
  ArrayList firstPos;
  grid2 = genArr(grid);
  char[] findStr = find.toCharArray();
  first = findStr[0];

  int[] currPos = null;
  firstPos = findInitPosition(first);

  if (firstPos.size() != 0) {
   for (int i = 0; i < firstPos.size(); i++) {
    currPos = (int[]) firstPos.get(i);
    findPpath(findStr, 0, currPos);
   }
  }
  if (count > 1000000000) {
   return -1;
  } else {
   return count;
  }

 }

 /**
  *
  * @param findStr
  *            尋找的路徑串
  * @param pos
  *            尋找串中當前字元的位置
  * @param currPos
  *            矩陣中要尋找的當前前字元的座標int[0]為x,int[1]為y
  *
  */
 private void findPpath(char[] findStr, int pos, int[] currPos) {
  char nextChar;
  int xLen, yLen, currX, currY;

  if (count > 1000000000) {
   return;
  }

  nextChar = findStr[pos + 1];

  int[] nextPos;

  yLen = grid2.length;
  xLen = grid2[0].length;
  currX = currPos[0];
  currY = currPos[1];

  /**
   * 在矩陣中從當前要找的字元開始在8個方向上尋找是否有路徑串中的下一個字元,
   *  在任何一個方向上如果找到了,都遞迴繼續尋找。
   */
  // up
  if (currX - 1 >= 0) {
   if (grid2[currX - 1][currY] == nextChar) {
    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currX - 1;
     nextPos[1] = currY;
     findPpath(findStr, pos + 1, nextPos);
    }

   }
  }

  if (currY + 1 < xLen && currX - 1 >= 0) {
   if (grid2[currX - 1][currY + 1] == nextChar) {

    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currX - 1;
     nextPos[1] = currY + 1;
     findPpath(findStr, pos + 1, nextPos);
    }
   }
  }

  // right
  if (currY + 1 < xLen) {
   if (grid2[currX][currY + 1] == nextChar) {
    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currX;
     nextPos[1] = currY + 1;
     findPpath(findStr, pos + 1, nextPos);
    }
   }
  }

  if (currX + 1 < xLen && currY + 1 < yLen) {
   if (grid2[currX + 1][currY + 1] == nextChar) {
    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currX + 1;
     nextPos[1] = currY + 1;
     findPpath(findStr, pos + 1, nextPos);
    }
   }
  }

  // down
  if (currX + 1 < yLen) {
   if (grid2[currX + 1][currY] == nextChar) {
    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currX + 1;
     nextPos[1] = currY;
     findPpath(findStr, pos + 1, nextPos);
    }
   }
  }

  if (currY - 1 >= 0 && currX + 1 < yLen) {
   if (grid2[currX + 1][currY - 1] == nextChar) {
    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currY - 1;
     nextPos[1] = currX + 1;
     findPpath(findStr, pos + 1, nextPos);
    }
   }
  }

  // left
  if (currY - 1 >= 0) {
   if (grid2[currX][currY - 1] == nextChar) {
    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currX;
     nextPos[1] = currY - 1;
     findPpath(findStr, pos + 1, nextPos);
    }
   }
  }

  if (currX - 1 >= 0 && currY - 1 >= 0) {
   if (grid2[currX - 1][currY - 1] == nextChar) {
    if (pos + 1 == findStr.length - 1) {
     count++;

    } else {
     nextPos = new int[2];
     nextPos[0] = currX - 1;
     nextPos[1] = currY - 1;
     findPpath(findStr, pos + 1, nextPos);
    }
   }
  }
 }

 /**
  * 在矩陣中找出所有的路徑首字元的位置,以list形式返回
  *
  * @param ch
  *            路徑的首字元
  * @return 矩陣中所有合格座標的數組
  */
 private ArrayList findInitPosition(char ch) {
  int[] chPos = null;
  ArrayList firstPos = new ArrayList();
  for (int i = 0; i < grid2.length; i++) {
   for (int j = 0; j < grid2[i].length; j++) {
    if (ch == grid2[i][j]) {
     chPos = new int[2];
     chPos[0] = i;
     chPos[1] = j;
     firstPos.add(chPos);
    }
   }
  }
  return firstPos;
 }

 /**
  * 將輸入的一維String數組資料轉換成二維的char矩陣
  *
  * @param inArr
  * @return
  */
 private char[][] genArr(String[] inArr) {
  char[][] grid = null;
  int x = 0, y = 0;
  if (inArr.length != 0) {
   x = inArr.length;
   y = inArr[0].length();
  }
  grid = new char[x][y];
  for (int i = 0; i < inArr.length; i++) {
   grid[i] = inArr[i].toCharArray();
   // for (int j = 0; j < inArr[i].length(); j++) {
   // grid[i][j] = inArr[i].substring(j, j + 1);
   // }
  }
  return grid;
 }

 public static void main(String[] args) {
  WordPath wp = new WordPath();
  // String[] inArr = { "ABC", "FED", "GHI" };
  // String find = "ABCDEFGHI";

  // String[] inArr = {"ABC",
  // "FED",
  // "GAI"};
  // String find = "ABCDEA";

  // String[] inArr = {"AA",
  // "AA"};
  // String find = "AAAA";

  // String[] inArr = {"AB"};
  // String find = "ABA";
  //  
  String[] inArr = { "ABABA", "BABAB", "ABABA", "BABAB", "ABABA" };
  String find = "ABABABBA";

  // String[] inArr = { "AAAAA", "AAAAA", "AAAAA", "AAAAA", "AAAAA" };
  // String find = "AAAAAAAAAAA";

  System.out.println("Path count:" + wp.countPaths(inArr, find));
 }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.