劍指Offer演算法題及答案Java完整版(二)
阿新 • • 發佈:2018-12-13
16、請設計一個函式,用來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑,路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則之後不能再次進入這個格子。例如 a b c e s f c s a d e e 這樣的3 X 4 矩陣中包含一條字串”bcced”的路徑,但是矩陣中不包含”abcb”路徑,因為字串的第一個字元b佔據了矩陣中的第一行第二個格子之後,路徑不能再次進入該格子。
package cn.ctgu.offer; /* * 題目: * 請設計一個函式,用來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。 * 路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。 * 如果一條路徑經過了矩陣中的某一個格子,則之後不能再次進入這個格子。 * 例如 a b c e s f c s a d e e 這樣的3 X 4 矩陣中包含一條字串"bcced"的路徑 * 但是矩陣中不包含"abcb"路徑,因為字串的第一個字元b佔據了矩陣中的第一行第二個格子之後,路徑不能再次進入該格子。 * * 思路: * 1、採用回溯法 * 2、將matrix字串模擬對映為一個字元矩陣(但並不實際建立一個矩陣) * 3、取一個boolean[matrix.length]標記某個字元是否已經被訪問過 * 3、如果沒找到結果,需要將對應的boolean標記值置回false,返回上一層進行其他分路的查詢 * * */ public class HashStrPath { public boolean hasPath(char[] matrix, int rows, int cols, char[] str) { boolean[] visited=new boolean[matrix.length]; for(int i=0;i<rows;i++) { for(int j=0;j<cols;j++) { if(searchFromHere(matrix,rows,cols,i,j,0,str,visited)) return true; } } return false; } private boolean searchFromHere(char[] matrix, int rows, int cols, int r, int c, int index, char[] str, boolean[] visited) { //matrix[r*cols+c]!=str[index]這是判斷位置(c,r)是否為字串所在位置 if(r<0 || r>=rows || c<0 ||c>=cols || matrix[r*cols+c]!=str[index] || visited[r * cols + c]) return false; if(index==str.length-1) return true; visited[r*cols+c]=true; if (searchFromHere(matrix,rows,cols,r - 1,c,index + 1,str,visited) || searchFromHere(matrix,rows,cols,r,c -1,index + 1,str,visited) || searchFromHere(matrix,rows,cols,r + 1,c,index + 1,str,visited) || searchFromHere(matrix,rows,cols,r,c + 1,index + 1,str,visited)) return true; visited[r*cols+c]=false; return false; } }
17、給定一個double型別的浮點數base和int型別的整數exponent。求base的exponent次方。
package cn.ctgu.offer; /* * 給定一個double型別的浮點數base和int型別的整數exponent。 * 求base的exponent次方。 * * * */ public class IntegerPower { public double Power(double base, int exponent) { return Math.pow(base, exponent); } /*手寫 * * 1.全面考察指數的正負、底數是否為零等情況。 * 2.寫出指數的二進位制表達,例如13表達為二進位制1101。 * 3.舉例:10^1101 = 10^0001*10^0100*10^1000。 * 4.通過&1和>>1來逐位讀取1101,為1時將該位代表的乘數累乘到最終結果。 * * */ public double Power2(double base, int n) { double res = 1,curr = base; int exponent; if(n>0){ exponent = n; }else if(n<0){ if(base==0) throw new RuntimeException("分母不能為0"); exponent = -n; }else{// n==0 return 1;// 0的0次方 } while(exponent!=0){ if((exponent&1)==1) res*=curr; curr*=curr;// 翻倍 exponent>>=1;// 右移一位 } return n>=0?res:(1/res); } public static void main(String[]args) { IntegerPower num=new IntegerPower(); System.out.println(num.Power2(12.34d, -4)); } }
18、LL今天心情特別好,因為他去買了一副撲克牌,發現裡面居然有2個大王,2個小王(一副牌原本是54張^_^)…他隨機從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿!!“紅心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是順子…..LL不高興了,他想了想,決定大\小 王可以看成任何數字,並且A看作1,J為11,Q為12,K為13。上面的5張牌就可以變成“1,2,3,4,5”(大小王分別看作2和4),“So Lucky!”。現在,要求你使用這幅牌模擬上面的過程,然後告訴我們LL的運氣如何, 如果牌能組成順子就輸出true,否則就輸出false。
package cn.ctgu.offer;
import java.util.Arrays;
/*
* 題目:
* LL今天心情特別好,因為他去買了一副撲克牌,發現裡面居然有2個大王,2個小王(一副牌原本是54張^_^)...
* 他隨機從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿!!
* “紅心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是順子.....LL不高興了
* 他想了想,決定大\小 王可以看成任何數字,並且A看作1,J為11,Q為12,K為13。
* 上面的5張牌就可以變成“1,2,3,4,5”(大小王分別看作2和4),“So Lucky!”。
* 現在,要求你使用這幅牌模擬上面的過程,然後告訴我們LL的運氣如何, 如果牌能組成順子就輸出true,否則就輸出false。
*
*
* 思路:
* 1、當牌不等於5張的時候返回false
* 2、對排進行排序(方便統計王(0)的數量以及比較是否有相同的牌,前後比較即可)
* 3、判斷第一張非0的牌和最後一張非0的牌的差是否超過4,如果超過4則不可能是順子
*
* */
public class IsContinu {
public boolean isContinuous(int [] numbers) {
if(numbers.length!=5) {
return false;
}
//排序
Arrays.sort(numbers);
//統計王的個數
int res=0;
for(int i=0;i<numbers.length;i++) {
if(numbers[i]==0) {
res=res+1;
continue;
}
//當王的數量小於等於3張的時候才需要判斷,等於4張的時候一定是順子
//判斷第一張非0的牌和最後一張非0的牌的差值吃否超過4
//判斷前後兩張牌是否相等,相等則不可能是順子
//此時的numbers[i]為第一個不為0的數,因為前面將為0的資料都遍歷完了(continue的作用是跳出本輪迴圈,繼續下一輪,所以0沒有遍歷完之前不會執行下面的語句)
if(res!=4&&(numbers[numbers.length-1]-numbers[i]>4||numbers[i]==numbers[i+1])) {
return false;
}else {
return true;
}
}
return true;
}
}
19、請實現一個函式用來判斷字串是否表示數值(包括整數和小數)。例如,字串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示數值。但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。
package cn.ctgu.offer;
/*
* 題目:
* 請實現一個函式用來判斷字串是否表示數值(包括整數和小數)。
* 例如,字串"+100","5e2","-123","3.1416"和"-1E-16"都表示數值。
* 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
*
*
* 思路:
* 1、先掃描字元是否是以+、-開頭,如果是則判斷下一個字元是否為數字,只有數字才能通過,否則該字串不表示數值;
* 如果不是+、-,則判斷它是否是數字
* 2、如果是數字則進行下一個字元判斷,判斷它是否為數字,如果不是則進行"."判斷和"E、e"判斷,反正第二個字元只能為數字或者"E、e"(第一個字元如果為'+、-'則第二個字元只能為數字)
* 如果第一個字元為數字,則第二個字元可以為('-、E、e、.')
*
*
* */
public class IsNumber {
private int index=0;
public boolean isNumberic(char[] str) {
if(str.length<1)
return false;
boolean flag=scanInteger(str);
if(index<str.length && str[index]=='.') {
index++;
flag=scanUnsignedInteger(str)||flag;//字元如果不為數字則返回false
}
if(index<str.length && (str[index]=='E'||str[index]=='e')) {
index++;
flag=flag && scanInteger(str);
}
return flag && index==str.length;
}
//判斷字元是否是以+或-號開頭
private boolean scanInteger(char[] str) {
if(index<str.length &&(str[index]=='+'||str[index]=='-'))
index++;
//如果不是+、-就判斷是否為數字
return scanUnsignedInteger(str);
}
private boolean scanUnsignedInteger(char[] str) {
int start=index;
while(index<str.length && str[index]>='0'&& str[index]<='9')
index++;
return start<index;//是否存在整數
}
}
20、輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的陣列的任意兩個數字都互不相同。說明:二叉搜尋樹的根節點大於左子樹,右節點大於根節點
package cn.ctgu.offer;
/*
* 輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。
* 假設輸入的陣列的任意兩個數字都互不相同。
* 說明:二叉搜尋樹的根節點大於左子樹,右節點大於根節點
*
* 思路:
* 1、採用遞迴
* 2、去掉根節點,也就是陣列的最後一個元素,小於最後一個節點的為左子樹,大於根節點的為右子樹
* 3、如果左子樹和右子樹都滿足左節點小於根節點、右節點大於根節點則為true,否則為true
*
*
* */
public class JudgeBST {
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence.length==0) {
return false;
}
return IsBst(sequence,0,sequence.length-1);
}
public boolean IsBst(int[]sequence,int start,int end ) {
if(end<=start) {//當只有一個元素時,則為真
return true;
}
int i=start;
for(;i<end;i++) {
if(sequence[i]>sequence[end]) {//當找到某個節點大於根節點,則從該元素開始直到end-1(倒數第二個元素),都為左子樹
break;
}
}
for(int j=i;j<end;j++) { //如果右子樹中存在小於根節點的元素,則返回false,即該陣列不是二叉搜尋樹的後序遍歷
if(sequence[j]<sequence[end]) {
return false;
}
}
return IsBst(sequence,start,i-1) && IsBst(sequence,i,end-1);
}
}
21、一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法
package cn.ctgu.offer;
/*
* 一隻青蛙一次可以跳上1級臺階,也可以跳上2級。
* 求該青蛙跳上一個n級的臺階總共有多少種跳法
*
* 思路:當前臺階的跳法總數=當前臺階後退一階的臺階的跳法總數+當前臺階後退二階的臺階的跳法總數
*
*
* 使用動態規劃來求解該問題,動態規劃適合求解最優解問題。
* 1、先構造出最優子結構
* 2、建立遞迴關係
* 3、計算最優值
* 4、求解最優解
*
* */
public class JumpFloor {
public int JumpFloors(int target) {
if(target==1) {
return 1;
}
if(target==2) {
return 2;
}
int one=1;//當前臺階後退二階的臺階的跳法總數(初始值當前臺階是第3階)
int two=2;//當前臺階後退一階的臺階的跳法總數(初始值當前臺階是第3階)
int result=0;// 當前臺階的跳法總數
for(int i=2;i<target;i++) {
result=one+two;
one=two;//後退一階在下一次迭代變為後退兩階
two=result;//當前臺階在下一次迭代變為後退一階
}
return result;
}
public static void main(String[]args) {
JumpFloor dy=new JumpFloor();
System.out.println(dy.JumpFloors(3));
}
}
22、一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
package cn.ctgu.offer;
/*
*一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。
*求該青蛙跳上一個n級的臺階總共有多少種跳法。
*
* 思路:設跳上第n階的跳法為f(n)
* 即 f(n)=f(n-1)+f(n-2)+f(n-3)+...+f(1)+1
*
* 1就是直接跳上第n階樓梯的跳法
*
* */
public class JumpFloor2 {
public int JumpFloor(int target) {
int[]ways=new int[target+1];
ways[0]=1;
ways[1]=1;//跳上一級階梯有一種跳法
if(target==0) {
return 0;
}
else {
for(int i=2;i<=target;i++) {
ways[i]=0;//相當於那個1,也就是直接跳上第n階樓梯的跳法
for(int j=0;j<i;j++) {
ways[i]=ways[i]+ways[j];
}
}
return ways[target];
}
}
public static void main(String[]args) {
JumpFloor2 dy=new JumpFloor2();
System.out.println(dy.JumpFloor(5));
}
}
23、隨機指定一個數m,讓編號為0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中。從他的下一個小朋友開始,繼續0…m-1報數….這樣下去….直到剩下最後一個小朋友。可以不用表演,並且拿到牛客名貴的“名偵探柯南”典藏版(名額有限哦!!^_^)。請你試著想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)
package cn.ctgu.offer;
import java.util.LinkedList;
/*
* 題目:
* 隨機指定一個數m,讓編號為0的小朋友開始報數。
* 每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中。
* 從他的下一個小朋友開始,繼續0...m-1報數....這樣下去....直到剩下最後一個小朋友。
* 可以不用表演,並且拿到牛客名貴的“名偵探柯南”典藏版(名額有限哦!!^_^)。
* 請你試著想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)
*
*
* 思路:
* 1、將所有的數封裝成一個LinkedList
* 2、每次刪除的都是第m-1個元素,它的索引可以通過公式:index=(index+m-1)%(環的長度)得到
* 3、index是指開始那個元素的索引,比如,因為每次報數都是從0開始,m為2的話刪除的必定為1(m=2,2-1=1)
* 4、將原始索引為1的刪除了的話,下一個開始的元素報0的數為原始索引為2的元素(由於是連結串列,則刪除了索引為1的元素
* 後面的元素自然前移,即原來索引為2的元素自然為1,也就是被刪除的原索引本身)
*
* */
public class LastRemain {
public int LastRemaining_Solution(int n, int m) {
LinkedList<Integer>list=new LinkedList<Integer>();
//將所有的數封裝到LinkedList中
for(int i=0;i<n;i++) {
list.add(i);
}
//刪除元素
int index=0;
while(list.size()>1) {
index=(index+m-1)%list.size();
list.remove(index);
}
return list.size()==1?list.get(0):-1;
}
}
24、例如,字元序列S=”abcXYZdef”,要求輸出迴圈左移3位後的結果,即“XYZdefabc”。
package cn.ctgu.offer;
/*
* 題目:
* 例如,字元序列S=”abcXYZdef”,要求輸出迴圈左移3位後的結果,即“XYZdefabc”。
*
* 思路:
* 1、將字串轉成字串陣列
* 2、左移k位就把前k位取出來接在原陣列的後面
*
*
* */
public class LeftRotateStr {
public String LeftRotateString(String str,int n) {
int len=str.length();
if(len==0) {
return "";
}
if(n>len) {
n=n-len;
}
char[]strArray=str.toCharArray();
char[]newArray=new char[len];
for(int i=n;i<len;i++) {
newArray[i-n]=strArray[i];
}
for(int j=0;j<n;j++) {
newArray[len-n+j]=strArray[j];
}
return String.valueOf(newArray);
}
public static void main(String[]args) {
LeftRotateStr solution=new LeftRotateStr();
String s="abcXYZdef";
String str=solution.LeftRotateString(s, 3);
System.out.println(str);
}
}
25、在一個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。
/*兩種思路
一種是:
把每一行看成有序遞增的陣列,
利用二分查詢,
通過遍歷每一行得到答案,
時間複雜度是nlogn
*/
public class Solution {
public boolean Find(int [][] array,int target) {
for(int i=0;i<array.length;i++){
int low=0;
int high=array[i].length-1;
while(low<=high){
int mid=(low+high)/2;
if(target>array[i][mid])
low=mid+1;
else if(target<array[i][mid])
high=mid-1;
else
return true;
}
}
return false;
}
}
/*
另外一種思路是:
利用二維陣列由上到下,由左到右遞增的規律,
那麼選取右上角或者左下角的元素a[row][col]與target進行比較,
當target小於元素a[row][col]時,那麼target必定在元素a所在行的左邊,
即col--;
當target大於元素a[row][col]時,那麼target必定在元素a所在列的下邊,
即row++;
*/
public class Solution {
public boolean Find(int [][] array,int target) {
int row=0;
int col=array[0].length-1;
while(row<=array.length-1&&col>=0){
if(target==array[row][col])
return true;
else if(target>array[row][col])
row++;
else
col--;
}
return false;
}
}
26、給定一個數組和滑動視窗的大小,找出所有滑動窗口裡數值的最大值。例如,如果輸入陣列{2,3,4,2,6,2,5,1}及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為{4,4,6,6,6,5};針對陣列{2,3,4,2,6,2,5,1}的滑動視窗有以下6個:{[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1},{2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
package cn.ctgu.offer;
import java.util.ArrayList;
/*
* 題目:
* 給定一個數組和滑動視窗的大小,找出所有滑動窗口裡數值的最大值。
* 例如,如果輸入陣列{2,3,4,2,6,2,5,1}及滑動視窗的大小3
* 那麼一共存在6個滑動視窗,他們的最大值分別為{4,4,6,6,6,5};
* 針對陣列{2,3,4,2,6,2,5,1}的滑動視窗有以下6個:
* {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1},
* {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
*
* 思路:
* 1、每隔一個視窗長度找出最大的值
* 2、將最大的值新增進列表
* */
public class MaxInWindow {
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
ArrayList<Integer>list=new ArrayList<Integer>();
if(size>num.length||size==0)
return list;
for(int i=0;i<=num.length-size;i++) {
int max=num[i];
for(int j=i+1;j<i+size;j++) {
if(num[j]>max) {
max=num[j];
}
}
list.add(max);
}
return list;
}
}
27、歸併排序演算法
package cn.ctgu.offer;
import java.util.Arrays;
/*
* 歸併排序
*
* */
public class MergeSort {
public static void sort(int []arr) {
//排序前,先建好一個長度等於原陣列長度的臨時陣列,避免遞迴中頻繁開闢空間
int[] temp=new int[arr.length];
sort(arr,0,arr.length-1,temp);
}
private static void sort(int[] arr, int left, int right, int[] temp) {
if(left<right) {
int mid=(left+right)/2;
//左邊歸併排序,使得左子序列有序
sort(arr,left,mid,temp);
//右邊歸併排序,使得右子序列有序
sort(arr,mid+1,right,temp);
//將兩個有序子數組合並操作
merge(arr,left,mid,right,temp);
}
}
private static void merge(int[] arr, int left, int mid, int right, int[] temp) {
//左序列指標
int i=left;
//右序列指標
int j=mid+1;
//臨時陣列指標
int t=0;
while(i<=mid && j<right) {
if(arr[i]<=arr[j]) {
temp[t]=arr[i];
t++;
i++;
}else{
temp[t]=arr[j];
t++;
j++;
}
}
while(i<=mid) {//將左邊剩餘元素填充進temp中
temp[t]=arr[i];
t++;
i++;
}
while(j<=right) {//將右序列剩餘元素填充進temp中
temp[t]=arr[j];
t++;
j++;
}
t=0;
//將temp中的元素全部拷貝到原陣列中
while(left<=right) {
arr[left]=temp[t];
left++;
t++;
}
}
public static void main(String []args){
int []arr = {9,8,7,6,5,4,3,2,1};
sort(arr);
System.out.println(Arrays.toString(arr));
}
}
28、輸入一個正整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。例如輸入陣列{3,32,321},則打印出這三個數字能排成的最小數字為321323。
package cn.ctgu.offer;
/*
* 題目:
* 輸入一個正整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。
* 例如輸入陣列{3,32,321},則打印出這三個數字能排成的最小數字為321323。
*
* 思路:
* 兩兩比較,自定義一個比較大小的函式
* 比較兩個字串s1, s2大小的時候,先將它們拼接起來
* 比較s1+s2,和s2+s1那個大,如果s1+s2大,那說明s2應該放前面
* 所以按這個規則,s2就應該排在s1前面。
*
* */
public class MinArrayNumber {
public String PrintMinNumber(int [] numbers) {
String str="";
for(int i=0;i<numbers.length;i++) {
for(int j=i+1;j<numbers.length;j++) {
int a=Integer.valueOf(numbers[i]+""+numbers[j]);
int b=Integer.valueOf(numbers[j]+""+numbers[i]);
if(a>b) {
int t=numbers[i];
numbers[i]=numbers[j];
numbers[j]=t;
}
}
}
for(int i=0;i<numbers.length;i++) {
str+=String.valueOf(numbers[i]);
}
return str;
}
public static void main(String[]args) {
MinArrayNumber solution=new MinArrayNumber();
int[] num= {3,32,321};
String str=solution.PrintMinNumber(num);
System.out.println(str);
}
}
29、定義棧的資料結構,請在該型別中實現一個能夠得到棧最小元素的min函式。
package cn.ctgu.offer;
import java.util.Iterator;
import java.util.Stack;
/*
* 定義棧的資料結構,請在該型別中實現一個能夠得到棧最小元素的min函式。
*
*
*
*
* */
public class MinStack {
Stack<Integer> stack=new Stack<Integer>();
public void push(int node) {
stack.push(node);
}
public void pop() {
stack.pop();
}
public int top() {
return stack.peek(); //棧頂元素(也就是最後一個元素)
}
public int min() {
int min = stack.peek();
int tmp=0;
Iterator<Integer> iterator = stack.iterator();
while (iterator.hasNext()){
tmp = iterator.next();
if (min>tmp){
min = tmp;
}
}
return min;
}
}
30、地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。例如,當k為18時,機器人能夠進入方格(35,37),因為3+5+3+7 = 18。但是,它不能進入方格(35,38),因為3+5+3+8 = 19。請問該機器人能夠達到多少個格子?
package cn.ctgu.offer;
/*
* 題目:
* 地上有一個m行和n列的方格。
* 一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格
* 但是不能進入行座標和列座標的數位之和大於k的格子。
* 例如,當k為18時,機器人能夠進入方格(35,37),因為3+5+3+7 = 18。
* 但是,它不能進入方格(35,38),因為3+5+3+8 = 19。請問該機器人能夠達到多少個格子?
*
* 思路:
* 1、回溯法
* 2、從(0,0)開始走,每成功走一步標記當前位置為true,然後從當前位置往四個方向探索
* 返回1+4個方向的探索值之和
* 3、探索時,判斷當前結點是否可達的標準為:
* 1)當前結點在矩陣內
* 2)當前結點未被訪問過
* 3)當前結點滿足limit限制
*
* */
public class MoveCount {
public int movingCount(int threshold, int rows, int cols) {
boolean[][]visited=new boolean[rows][cols];
return countingSteps(threshold,rows,cols,0,0,visited);
}
private int countingSteps(int limit, int rows, int cols, int r, int c, boolean[][] visited) {
if(r<0||r>=rows||c<0||c>=cols||visited[r][c]||bitSum(r)+bitSum(c)>limit)
return 0;
visited[r][c]=true;
return countingSteps(limit,rows,cols,r - 1,c,visited)
+ countingSteps(limit,rows,cols,r,c - 1,visited)
+ countingSteps(limit,rows,cols,r + 1,c,visited)
+ countingSteps(limit,rows,cols,r,c + 1,visited)
+ 1;
}
private int bitSum(int t) {
int count=0;
while(t!=0) {
count=count+t%10;
t=t/10;
}
return count;
}
}