双指针算法题,你了解多少?

一.移动零

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/move-zeroes/

解题思路:

代码实现:

class Solution {
    public void moveZeroes(int[] nums) {
       for(int cur=0,dest=-1;cur<nums.length;cur++){
        if(nums[cur]!=0){
            dest++;
            int tmp=nums[dest];
            nums[dest]=nums[cur];
            nums[cur]=tmp;
        }
       }
    }
}

二、复写零 

题目链接:

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/duplicate-zeros/description/

解题思路:

代码实现:

class Solution {
    public void duplicateZeros(int[] array) {
        int dest=-1;
        int cur=0;
        //找到最后一个复写的值
        while(dest<array.length){
            if(array[cur]==0){
                dest+=2;
            }else{
                dest++;
            }
            if(dest>=array.length-1){
                break;
            }
            cur++;
        }
        //处理特殊情况
        if(dest==n){
            arr[n-1]=0;
            cur--;
            dest-=2;
        }
        //从后向前复写
        for(;cur>=0;cur--){
            if(array[cur]==0){
                array[dest]=array[cur];
                dest--;
                array[dest]=array[cur];
                dest--;
            }else{
                array[dest]=array[cur];
                dest--;
            }
        }
    }
}

 三、快乐数

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/happy-number/description/

解题思路: 

代码实现:

class Solution {
    //对n的每一位求平方和
    public int bitSum(int n){
        int sum=0;
        while(n!=0){
            int end=(n%10)*(n%10);
            sum+=end;
            n=n/10;
        }
        return sum;
    }
    public boolean isHappy(int n) {
        int slow = n;
        //不能slow和fast都等于n,这样会倒是循环进不去,无法判断
        int fast = bitSum(n);
        while(slow!=fast){
                slow=bitSum(slow);
                fast=bitSum(fast);
                fast=bitSum(fast);
        }
       return slow==1;
    }
}

 四、盛水最多的容器

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/container-with-most-water/description/

解题思路:

代码实现:

方法一:暴力枚举

实际上就是两层for循环,把所有的情况列举出来,但是这种方法在力扣中会超时

class Solution {
        public int maxArea(int[] height) {
            int max=0;
            for(int dest=0;dest<height.length-1;dest++){
                for(int cur=dest+1;cur<height.length;cur++){
                    int val=(cur-dest)*Math.min(height[dest],height[cur]);
                    if(max<val){
                        max=val;
                    }
                }
            }
            return max;
        }
    }
方法二:最优解

也就是解题思路中对应的解法

class Solution {
        public int maxArea(int[] height) {
            int left=0;
            int right=height.length-1;
            int vMax=0;//记录盛水最多的容器
            while(left<right){
                int v=Math.min(height[left],height[right])*(right-left);
                if(v>vMax){
                    vMax=v;
                }
                if(height[left]>height[right]){
                    right--;
                }else{
                    left++;
                }
            }
            return vMax;
        }
    }

五、有效三角形的个数

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/valid-triangle-number/description/

解题思路:

代码实现:

 public int triangleNumber(int[] nums) {
        // 先进行排序
        Arrays.sort(nums);
        int c = nums.length - 1;
        int count = 0;
        while (c >= 2) {
            //每一次大循环结束,a,b都需要回到相应的位置
            int a = 0;
            int b = c - 1;
            while (a < b) {
                if (nums[a] + nums[b] > nums[c]) {
                    count += b - a;
                    b--;
                } else {
                    a++;
                }
            }
            c--;
        }
        return count;
    }

六、三数之和

题目链接:. - 力扣(LeetC​​​​​​ode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/1fGaJU/

解题思路:

代码实现:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList<>();
        Arrays.sort(nums);

        for (int i = nums.length - 1; i > 0; i--) {
            // 如果这个元素和上一个元素一样,直接跳过,避免重复
            while(i>=0){
                if(i!=nums.length-1 && i>0 && nums[i] == nums[i + 1]){
                    i--;
                }else{
                    break;
                }
            }
          
        
            int left = 0;
            int right = i - 1;
            while (left < right) {
                List<Integer> list1 = new ArrayList<>();
                //当最小的数nums[left]都大于0时,三数之和一定大于0,结束循环
                if(nums[left]>0){
                    break;
                }

                if (nums[left] + nums[right] + nums[i] > 0) {
                    right--;
                } else if (nums[left] + nums[right] + nums[i] < 0) {
                    left++;
                } else {
          

                    list1.add(nums[left]);
                    list1.add(nums[i]);
                    list1.add(nums[right]);
                    list.add(list1);
                    left++;
                    right--;
                    //去重
                    while(left<right && nums[left]==nums[left-1]){
                        left++;
                    }
                    while(left<right && nums[right]==nums[right+1]){
                        right--;
                    }
                }
            }
        }
        return list;
    }
}

七、四数之和

题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/4sum/description/

解题思路:

本题解题思路于第六题大致相同,无非是多固定一个数,多了一层循环,当时我们需要对这四个数进行去重操作,并且需要定义一个long类型的变量来存储四数之和与target比较大小,否则测试时会导致数据溢出。

代码实现:

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> list = new ArrayList<>();
        Arrays.sort(nums);

        for (int i = nums.length - 1; i > 0; i--) {
            while (i >= 0) {
                if (i != nums.length - 1 && i > 0 && nums[i] == nums[i + 1]) {
                    i--;
                } else {
                    break;
                }
            }

            for (int j = i - 1; j > 0; j--) {
                //这里的去重条件区别于三数之和
                while (j >= 0) {
                    if (j != nums.length - 1 - 1 && j > 0 && nums[j] == nums[j + 1] && j + 1 != i) {
                        j--;
                    } else {
                        break;
                    }
                }

                int left = 0;
                int right = j - 1;
                while (left < right) {
                    // 由于部分测试代码的数据太大,直接相加会导致溢出,我们可以定义一个long类型的变量来存储四数之和
                    long sum = nums[left] + nums[right];
                    sum+=nums[i]+nums[j];
                    if (sum > target) {
                        right--;
                    } else if (sum < target) {
                        left++;
                    } else {
                        list.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        left++;
                        right--;
                        
                        // 去重
                        while (left < right && nums[left] == nums[left - 1]) {
                            left++;
                        }
                        while (left < right && nums[right] == nums[right + 1]) {
                            right--;
                        }
                    }
                }
            }
        }
        return list;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值