算法-双指针

目录

移动零

关键是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;
        }
    }
}
相关推荐
rannn_1114 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
数模竞赛Paid answer4 小时前
2026年华东杯数学建模B题医药物流安排问题解题全过程文档及程序
算法·数学建模·数据分析·华东杯
不会代码的小猴4 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
AI备案指南-满满5 小时前
大模型与算法备案全流程详解:从零到通过的完整指南
人工智能·算法·备案·大模型备案·算法备案
江畔柳前堤5 小时前
LLM 训练核心机制深度解析:Warmup、Cosine Decay 与 Perplexity 的完整知识体系
网络·人工智能·深度学习·算法·机器学习·语音识别
一只旭宝5 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
良木林6 小时前
子串 - LeetCode hot 100
算法·leetcode·职场和发展
陌诺曦.6 小时前
Python扩展小练习
算法
coder!mq7 小时前
说几个常见的语法糖?
java·开发语言·算法