目录
力扣1089复写零(难度较大,要重点理解,可以记不住咋写,但要记住想法)
public static void moveZeroes(int[] nums) { int cur=0; int dest=-1; while(cur<nums.length&&dest<cur){ if(nums[cur]!=0){ dest++; int tmp=nums[cur]; nums[cur]=nums[dest]; nums[dest]=tmp; } cur++; } }
数组中这种移动元素都是双指针
先根据异地操作,然后优化成双指针下的 就地操作
异地操作
就地操作:(这个问题从左向右是肯定不行的,因为会覆盖原来的数字)
cur指最后一个复写的值
dest在最后一个位置(此时使用下面这个方法,可以正好让两个都在他们自己的位置上)
面对特例(此处将n-1位置的值设置为0。)
class Solution { public static void duplicateZeros(int[] arr) { int dest=0; int cur=0; while(cur<arr.length){ if(arr[cur]==0){ dest++; } if(dest>=arr.length-1){ break; } cur++; dest++; } if(dest==arr.length){ arr[arr.length-1]=0; cur--; dest-=2; } while(dest>0){ if(arr[cur]!=0){ arr[dest]=arr[cur]; dest--; } if(arr[cur]==0){ arr[dest--]=0; if(dest==0){ break; } arr[dest--]=0; } cur--; } } }
换句话说,我们需要找出循环的点。
class Solution {
//返回n这个数每一位上的平方和
public int bitSum(int n){
int sum=0;
while(n!=0){
int t=n%10;
sum+=t*t;
n=n/10;
}
return sum;
}
//谈谈写代码时候的困境,不知道怎么来写,才让指针走一步,没想到可以额外定义一个函数,然后将n这个值传给这个函数,就相当于指针动了一步
public boolean isHappy(int n) {
int fast=bitSum(n);
int slow=n;
while(slow!=fast){ //找相遇点,因为有环,所以一定会相遇
slow=bitSum(slow);
fast=bitSum(bitSum(fast));
}
return slow==1;
}
}
法1.暴力枚举,固定左边,计算所有的右边,然后枚举所有的数字,(两层循环,超时)
方法2:双指针
假如他的左边的数字小,那么就移动左边,右边的数字小就移动右边,是否移动,是通过比较双方数字的大小,来去做指针的移动的
class Solution { public int maxArea(int[] height) { int cur=0; int end=height.length-1; int ret=0; int i=0; while(cur<end){ int v=Math.min(height[end],height[cur])*(end-cur); ret=Math.max(ret,v); if(height[cur]<height[end]){ cur++; }else{ end--; } } return ret; } }