算法-双指针

目录

移动零

关键是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;
        }
    }
}
相关推荐
阿Y加油吧18 小时前
两道数组算法题复盘:多数元素 & 颜色分类
算法·leetcode·职场和发展
夏日听雨眠19 小时前
排序(选择排序 ,冒泡排序,归并排序)
数据结构·算法·排序算法
珠海西格电力19 小时前
零碳园区的能源成本优势具体体现在哪些方面
大数据·人工智能·算法·架构·能源
Donk_6719 小时前
Shell 数组实践
linux·算法·bash
数智工坊19 小时前
【DACS论文阅读】跨域混合采样如何让语义分割模型从合成数据无缝迁移到真实世界
论文阅读·人工智能·算法·机器人·无人机
And_Ii19 小时前
LeetCode 026. 重排链表
算法·leetcode·链表
心中有国也有家19 小时前
catlass 算子模板库中的 FlashAttention 高性能实现
笔记·算法
是娇娇公主~20 小时前
力扣——146.LRU缓存详解
算法·leetcode·缓存
我不是懒洋洋20 小时前
【C++】类和对象( 类的定义、实例化、 this指针、 C++和C语言实现Stack对比)
c语言·开发语言·数据结构·c++·经验分享·算法·visual studio
_深海凉_20 小时前
LeetCode热题100-路径总和 III
算法·leetcode·职场和发展