Leetcode总结:双指针

前言

双指针的思想非常重要,这是一种较低空间复杂度的算法。以下题目除了双指针还可以用其它解法,但是可以从复杂度角度分析与其他算法的优缺点。

本文参考链接:力扣(LeetCode)作者:鲂
链接:https://leetcode-cn.com/circle/discuss/j9HySW/

计算 X数之和 / X数之差

  1. 1. 两数之和:解法很多,可以用暴力循环、HashMap,也可以使用双指针(排序+双指针,先备份一份数组,对原数组进行排序,找到目标数值,寻找备份里相同的数值,找到它们的下标),分析一下时间和空间复杂度。
  2. 167. 两数之和 II - 输入有序数组:与上一题一样,只是数组已按照升序排列,可以使用HashMap、双指针法。
  3. 剑指 Offer 57. 和为s的两个数字:与上一题同一类型,递增序列,但返回值为数本身,而不是下标,可能会有多个答案,任意输出一个。
  4. 面试题 16.24. 数对和:要输出数组中两数之和为指定值的所有整数对。哈希表辅助实现或者双指针法(先对数组进行排序处理)。
  5. 653. 两数之和 IV - 输入 BST:给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。①双指针法:先用中序遍历进行排序;②哈希查找:遍历整棵树。
  6. 15. 三数之和:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。解决:双指针法,先将数组排序,固定3个指针中最左数字的指针,另外两个指针分设在数组两端(除去最左边指针的部分),通过双指针交替向中间移动,注意去重。
  7. 16. 最接近的三数之和:与上一题类似,寻找三数之和与目标值最近的数值,因此需要一个三数之和的变量用于记录和比较。
  8. 18. 四数之和:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。解决:在三数之和的基础上再加一个循环,参考三数之和解法。
  9. 面试题 16.06. 最小差:给定两个整数数组a和b,计算具有最小差绝对值的一对数值(每个数组中取一个值),并返回该对数值的差。解决:先将数组排序,再用双指针向后扫描。注意两个数组中元素在计算差值的过程中可能出现溢出的情况,因此转成整型计算,最后再转为int类型。

柱状图装水

此类题目,双指针法只是其中一种解法。接雨水虽然是hard,但是在面试中出现频率较高。

  1. 11. 盛最多水的容器:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
  2. 42. 接雨水:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
  3. 面试题 17.21. 直方图的水量:此题与上一题 接雨水 代码一样。解法:动态规划、双指针等,注意复杂度分析。

排序

当题目中指定原地修改、额外常数空间之类的字眼时,可以尝试用双指针思想。
当题目输出和索引(下标)有关时,可以尝试用双指针思想。

  1. 31. 下一个排列:实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列,如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。必须 原地 修改,只允许使用额外常数空间。
  2. 面试题 16.16. 部分排序:给定一个整数数组,编写一个函数,找出索引m和n,只要将索引区间[m,n]的元素排好序,整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n],若不存在这样的m和n(例如整个数组是有序的),请返回[-1,-1]。
  3. 26. 删除排序数组中的重复项:给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组 并在使用O(1)额外空间的条件下完成。解决:两个指针一前一后,比较是否重复,然后后移。
  4. 88. 合并两个有序数组:给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。解决:从后往前比较进入数组。

找值

  1. 162. 寻找峰值:峰值元素是指其值大于左右相邻值的元素。给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。
  2. 剑指 Offer 59 - I. 滑动窗口的最大值:给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。解决:维护一个单调的双向队列。

调整位置

  1. 283. 移动零:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。**解决:**双指针,第一次遍历left指针记录非零个数,把非零都给nums[left],第二次把剩下的末尾元素全部赋值为零。
  2. 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。解决:两个指针分别在数组左右两端,循环执行,左指针从左往右寻找偶数,右指针从右往左寻找奇数,将两个交换。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值