Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
  • 哈希表

  • 双指针

    • 同向双指针
    • 双向双指针
      • 167. 两数之和 II
      • 611. 有效三角形的个数
      • 15. 三数之和
      • 11. 盛最多水的容器
      • 42. 接雨水
      • 581. 最短无序连续子数组
      • 633. 平方数之和
      • 31. 下一个排列
    • 滑动窗口
    • 分组循环
  • 数组

  • 字符串

  • 链表

  • 树

  • 回溯

  • 动态规划

  • 图

  • 二分查找

  • 贪心

  • 栈&队列

  • 堆

  • 位运算

  • 数据结构设计

  • rui的精选题单

  • 笔试真题

  • LeetCode周赛

  • ACM模式输入输出
  • 数学

  • 数据结构与算法
  • 双指针
Nreal
2023-11-01
目录

双向双指针

# 167. 两数之和 II (opens new window)

有序数组

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int l = 0,r = numbers.length-1;
        while(l<=r){
            int sum = numbers[l]+numbers[r];
            if(target == sum){
                return new int[]{l+1,r+1};
            }else if(target<sum){
                r--;
            }else{
                l++;
            }
        }
        return new int[]{-1,-1};
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 611. 有效三角形的个数 (opens new window)

# 15. 三数之和 (opens new window)

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0) return res;
            if(i>0 && nums[i]==nums[i-1]) continue;
            int l=i+1,r=nums.length-1;
            while(l<r){
                int sum = nums[i]+nums[l]+nums[r];
                if(sum>0) r--;
                else if(sum<0) l++;
                else{
                    res.add(Arrays.asList(nums[i],nums[l],nums[r]));
                    while(r>l && nums[r]==nums[r-1]){
                        r--;
                    }
                    while(r>l && nums[l]==nums[l+1]){
                        l++;
                    }
                    l++;
                    r--;
                }
            }
        }
        return res;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 11. 盛最多水的容器 (opens new window)

class Solution {
    public int maxArea(int[] height) {
        int ans = 0;
        int l=0,r=height.length-1;
        int area = 0;
        while(l<r){
            area = (r-l) * Math.min(height[l],height[r]);
            ans = Math.max(ans,area);
            if(height[l]<height[r]){
                l++;
            }else{
                r--;
            }
        }
        return ans;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 42. 接雨水 (opens new window)

方法一:前后缀数组

class Solution {
    public int trap(int[] height) {
        int n = height.length;
        int[] preMax = new int[n];
        int[] sufMax = new int[n];
        preMax[0] = height[0];
        for(int i=1;i<n;i++){
            preMax[i] = Math.max(preMax[i-1],height[i]);
        }
        sufMax[n-1] = height[n-1];
        for(int i=n-2;i>=0;i--){
            sufMax[i] = Math.max(sufMax[i+1],height[i]);
        }
        int ret = 0;
        for(int i=0;i<n;i++){
            ret += Math.min(preMax[i],sufMax[i])-height[i];
        }
        return ret;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

方法二:双指针

class Solution {
    public int trap(int[] height) {
        int l=0,r=height.length-1,ans=0;
        int preMax = 0;
        int sufMax = 0;
        while(l<=r){
            preMax = Math.max(preMax,height[l]);
            sufMax = Math.max(sufMax,height[r]);
            if(preMax<sufMax){
                ans += preMax-height[l++];
            }else{
                ans += sufMax-height[r--];
            }
        }
        return ans;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 581. 最短无序连续子数组 (opens new window)

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        if(isSorted(nums)) return 0;
        int[] numsSorted = new int[nums.length];
        System.arraycopy(nums,0,numsSorted,0,nums.length);
        Arrays.sort(numsSorted);
        int l=0;
        while(nums[l] == numsSorted[l]){
            l++;
        }
        int r=nums.length-1;
        while(nums[r] == numsSorted[r]){
            r--;
        }
        return r-l+1;
    }
    boolean isSorted(int[] nums){
        for(int i=1;i<nums.length;i++){
            if(nums[i]<nums[i-1]){
                return false;
            }
        }
        return true;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 633. 平方数之和 (opens new window)

# 31. 下一个排列 (opens new window)

  1. 从后往前找第一个比自己后一位小的元素,确定其索引 i ;

  2. 从后往前找第一个比nums[i]大的元素下标 j ;

  3. 交换两个位置元素;

  4. 翻转 i+1 到 n-1的元素;

案例:

nums = [1,2,7,4,3,1]

  1. 倒序遍历找到第一组 前一个数比后一个数小的两个数 [2,7],索引为1;
  2. 从[7,4,3,1]中从后往前中找出比2大的第一个数:3,索引为j;
  3. 交换后:[1,3,7,4,2,1];
  4. 对3后面的数翻转:[1,3,1,2,4,7];
class Solution {
    public void nextPermutation(int[] nums) {
        int n = nums.length;
        int i = n-2;
        while(i>=0){
            if(nums[i]<nums[i+1])
                break;
            i--;
        }
        if(i>=0){
            int j = n-1;
            while(j>=0){
                if(nums[j]>nums[i]){
                    break;
                }
                j--;
            }
            swap(nums,i,j);
        }
        rev(nums,i+1,n-1);
    }
    void rev(int[] nums,int l,int r){
        while(l<r){
            swap(nums,l,r);
            l++;r--;
        }
    }
    void swap(int[] nums,int l,int r){
        int tmp = nums[l];
        nums[l] = nums[r];
        nums[r] = tmp;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
同向双指针
滑动窗口

← 同向双指针 滑动窗口→

Theme by Vdoing | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式