算法-双指针

目录

移动零

关键是i找到0,j找到非0,此时仅i<j才移动,否则j++后重新循环

java 复制代码
public class 移动零 {
    class Solution {
        public void moveZeroes(int[] nums) {
            int zero = 0;
            int nzero = 0;
            while (zero<nums.length && nzero<nums.length){
                while (nums[zero]!=0){
                    zero++;
                    if (zero>= nums.length)return;
                }
                while (nums[nzero]==0){
                    nzero++;
                    if (nzero>= nums.length)return;
                }

                if (zero < nzero){
                    int temp = nums[zero];
                    nums[zero++] = nums[nzero];
                    nums[nzero++] = temp;
                }else{
                    nzero++;
                }
            }
        }
    }
}

三数之和

排序+set去重 。用map记录每个元素,重复时 仅记录最后一个元素。

这题耗时太长了,但是最优解没时间看了。

java 复制代码
public class 三数之和 {
    class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            Map<Integer, Integer> map = new HashMap<>();// 对于重复元素这里只需要记最后一个index就行了
            HashSet<String> set = new HashSet<>();// 用于去重
            Arrays.sort(nums);
            ArrayList<List<Integer>> res = new ArrayList<>();
            for (int i = 0; i < nums.length; i++) {
                map.put(nums[i], i);
            }

            for (int i = 0; i < nums.length; i++) {
                for (int j = i+1; j < nums.length; j++) {
                    if (map.containsKey(-(nums[i]+nums[j])) && map.get(-(nums[i]+nums[j]))>j){
                        if (!set.contains(""+nums[i]+nums[j]+(-nums[i]-nums[j]))){
                            ArrayList<Integer> list = new ArrayList<>();
                            list.add(nums[i]);
                            list.add(nums[j]);
                            list.add(-nums[i]-nums[j]);
                            res.add(list);
                            set.add(""+nums[i]+nums[j]+(-nums[i]-nums[j]));
                        }
                    }
                }
            }
            return res;
        }
    }
}

盛最多水的容器

短板效应(贪心),如果移动长边那么宽度会减小,高度不变或减小,所以总的面积一定减小,只有移动短边才可能比原来的面积大,因此使用双指针向中间,不断移动短边并更新最大值。

java 复制代码
public class 盛最多水的容器 {
    class Solution {
        public int maxArea(int[] height) {
            int res = 0;
            int left = 0, right = height.length - 1;
            while (left < right){
                res = Math.max(res, Math.min(height[left], height[right])*(right-left));
                if (height[left]>height[right]) right--;
                else left++;
            }
            return res;
        }
    }
}

接雨水

"盛最多水的容器"每个位置是一条边,而该问题中每个位置可以看作一个桶,计算总的接水量就是每个位置的节水量的和(由整体到分解为子问题的思想),那么每个位置的最大接水量取决于min(该位置左边的最大高度,该位置右边的最大高度)

java 复制代码
public class 接雨水 {
    class Solution {
        public int trap(int[] height) {
            int res = 0;
            int[] lMax = new int[height.length + 2];
            int[] rMax = new int[height.length + 2];
            for (int i = 1; i <= height.length; i++) {
                lMax[i] = Math.max(lMax[i-1], height[i-1]);
            }
            for (int i = height.length; i >= 1; i--) {
                rMax[i] = Math.max(rMax[i+1], height[i-1]);
            }

            for (int i = 1; i <= height.length; i++) {
                res += Math.max(0, Math.min(lMax[i-1], rMax[i+1]) - height[i-1]);
            }
            return res;
        }
    }
}
相关推荐
hanlin0321 小时前
刷题笔记:力扣第43、67题(字符串计算)
笔记·算法·leetcode
yang_B62121 小时前
最小二乘法 拟合平面
算法·平面·最小二乘法
放下华子我只抽RuiKe521 小时前
深度学习全景指南:硬核实战版
人工智能·深度学习·神经网络·算法·机器学习·自然语言处理·数据挖掘
吴秋霖1 天前
【某音电商】protobuf聊天协议逆向
python·算法·protobuf
m0_587958951 天前
C++中的命令模式变体
开发语言·c++·算法
似水এ᭄往昔1 天前
【数据结构】--链表OJ
数据结构·算法·链表
2501_924952691 天前
代码生成器优化策略
开发语言·c++·算法
MORE_771 天前
leecode100-划分区间-贪心算法
算法·贪心算法
Book思议-1 天前
【数据结构实战】C语言实现栈的链式存储:从初始化到销毁,手把手教你写可运行代码
数据结构·算法·链表··408
Book思议-1 天前
【数据结构实战】川剧 “扯脸” 与栈的 LIFO 特性 :用 C 语言实现 3 种栈结构
c语言·数据结构·算法·