踩坑目录
二分
循环条件情况的忽略
- 力扣原题 排序数组查找元素
//正确代码
class Solution {
public int[] searchRange(int[] nums, int target) {
int leftindex=0,rightindex=nums.length-1;
int []num=new int[2]; num[0]=-1; num[1]=-1;
if(nums.length==0) return num;
//在这里,忘记掉==时也是要进入二分查找的,该死啊,艹! 记录一下
while(leftindex<=rightindex){
int midindex=(leftindex+rightindex)/2,mid=nums[midindex];
if(mid==target) {
num[0]=midindex; num[1]=num[0];
break;
}
else if(mid<target) leftindex=midindex+1;
else rightindex=midindex-1;
}
//nums[0]存放开始也许的位置
if(num[0]==-1) return num;
while(true) {
//如果前边相同,前提索引不会比0小
if(num[0]-1>=0&&(nums[num[0]-1]==nums[num[0]])) num[0]-=1;
else break;
}
while(true) {
//如果前边相同,
if(num[1]+1<=nums.length-1&&nums[num[1]+1]==nums[num[1]]) num[1]+=1;
else break;
}
return num;
}
}
- 总结
应该提前做好循环条件的判断,这种就典型属于举例过少,导致漏掉左索引==右索引的情况,该死啊,下回该想全点的
递归
计算目标时忽略掉参数需进入下一层才能利用
- 踩坑记录 力扣原题(动态规划用递归做) 目标和
计算值与目标和相等的话,必须将值传入到下一个递归方法才能比较,然而我是直接在本方法中比较啦,未在下一递归函数里比较,也就是未能将数组最后一位数字计入进去,在此踩过坑,记录下
//正确答案
class Solution {
public int findTargetSumWays(int[] nums, int S) {
return dfs(nums,0,S,0);
}
int dfs(int nums[],int cur,int tar,int index){
if(cur==tar&&index==(nums.length)) return 1;
else if(index==nums.length) return 0;
return dfs(nums,nums[index]+cur,tar,index+1)+dfs(nums,cur-nums[index],tar,index+1);
}
}
//错误答案
class Solution {
public int findTargetSumWays(int[] nums, int S) {
return dfs(nums,0,S,0);
}
public static int dfs(int nums[],int cur,int tar,int index){
if(index==nums.length) return 0;
if(cur==tar&&index==(nums.length-1)) return 1;
return dfs(nums,nums[index]+cur,tar,index+1)+dfs(nums,cur-nums[index],tar,index+1);
}
}
递归结束条件的优先级
力扣原题 单词搜索
- 贴上我的错误代码
//错误代码
class Solution {
public boolean exist(char[][] board, String word) {
if(word.length()==0) return false;
/*
遍历二维数组,找到切入点,进行深度回溯
*/
for(int i=0;i<board.length;i++){
for(int j=0;j<board[i].length;j++){
//找到切入点
if(board[i][j]==word.charAt(0)) {
if(dfs(board,i,j,word,0, new HashSet<List>())) return true;
}
}
}
return false;
}
public boolean dfs(char[][]board,int x,int y,String word, int index,Set<List> pos){
if(!(x<0||y<0||x>=board.length||y>=board[0].length)) {
//这里,1和2条件的结束优先级我没搞清,导致代码瞅啦半天都没看出毛病,记录下坑
//应该先考虑set里重复的路径,之后再考虑是否是正常结束结束标志,否则两个颠倒位置后,总是导致结果正确
1 if(index==(word.length()-1)&&board[x][y]==word.charAt(index)) return true;
Set<List> clone=new HashSet<>(pos);
List arrclone=new LinkedList<>(); arrclone.add(x);arrclone.add(y);
2 if(pos.contains(arrclone)) return false;
if(board[x][y]==word.charAt(index)) {
//复制坐标到set里
clone.add(arrclone);
return dfs(board,x+1,y,word,index+1,clone)|| dfs(board,x-1,y,word,index+1,clone)||
dfs(board,x,y+1,word,index+1,clone)|| dfs(board,x,y-1,word,index+1,clone);
}
}
return false;
}
}
- 正确代码
//正确
class Solution {
public boolean exist(char[][] board, String word) {
if(word.length()==0) return false;
/*
遍历二维数组,找到切入点,进行深度回溯
*/
for(int i=0;i<board.length;i++){
for(int j=0;j<board[i].length;j++){
//找到切入点
if(board[i][j]==word.charAt(0)) {
if(dfs(board,i,j,word,0, new HashSet<List>())) return true;
}
}
}
return false;
}
public boolean dfs(char[][]board,int x,int y,String word, int index,Set<List> pos){
if(!(x<0||y<0||x>=board.length||y>=board[0].length)) {
Set<List> clone=new HashSet<>(pos);
List arrclone=new LinkedList<>(); arrclone.add(x);arrclone.add(y);
if(pos.contains(arrclone)) return false;
if(index==(word.length()-1)&&board[x][y]==word.charAt(index)) return true;
if(board[x][y]==word.charAt(index)) {
//复制坐标到set里
clone.add(arrclone);
return dfs(board,x+1,y,word,index+1,clone)|| dfs(board,x-1,y,word,index+1,clone)||
dfs(board,x,y+1,word,index+1,clone)|| dfs(board,x,y-1,word,index+1,clone);
}
}
return false;
}
}
数组
二维数组
力扣原题 合并区间
- 首先感觉不难,但却连二维数组的定义都不清楚,困倒在二维数组的排序及遍历及定位元素上上
- 依然是考虑不全情况,对于前后有关联的数组,应该考虑长度为0,1时的情况
关于数组泛型equals的重写问题
- 举例
HashSet<int[]> set = new HashSet<>();
int []a=new int[]{1,2};
int []b=new int[]{1,2};
set.add(a);
System.out.println(set.contains(b));
猜猜打印结果?
结果是false ,不管是list还是map,数组作为泛型,再调用contains()时是无效的
- 再举例
HashSet<List> set = new HashSet<>();
LinkedList<Object> objects1 = new LinkedList<>();
LinkedList<Object> objects2 = new LinkedList<>();
objects1.add(1);
objects2.add(1);
set.add(objects1);
System.out.println(set.contains(objects2));
猜猜打印结果?
结果是true ,因为list默认重写过equals方法,再调用contains()时就是有效的;
字符串
关于字符串的==问题
力扣原题 单词拆分
- 举例
String a="123";
String d="123";
System.out.println(a == d);
猜猜执行结果?
结果是right,因为两者的地址是一样的;
- 再举例
String a="123";
String b="1";
String c="23";
System.out.println((b + c) == a);
猜猜执行结果?
结果是false,原因大概是b+c的形成的字符串和a的地址不一样,要比较值,最好用equals方法;
二叉树
关于二叉树深度回溯的一点小结
二叉树进行递归时,不需要去注重过程,可以从递归要结束的临界点入手,这样便于思考