[算法]-beat双指针

228 阅读5分钟

Two pointer 专题01

分类:

image.png

1、 左右指针相对运动:扫描整个数组,

模版:

Int left = 0, right = len -1;
While(left < right) {
	If(满足某条件) left++;
	Else right --;
}
Return res;

167. Two Sum II - Input array is sorted

Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Note: • Your returned answers (both index1 and index2) are not zero-based. • You may assume that each input would have exactly one solution and you may not use the same element twice.

Example 1: Input: numbers = [2,7,11,15], target = 9 Output: [1,2] Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.

  • 特点:有序数组,寻找满足一定条件的一个状态。
  • 代码:

image.png

587. 两数之和 - 不同组成

给一整数数组, 找到数组中有多少组 不同的元素对 有相同的和, 且和为给出的 target 值, 返回对数. 样例 例1: 输入: nums = [1,1,2,45,46,46], target = 47 输出: 2 解释:

1 + 46 = 47 2 + 45 = 47

例2: 输入: nums = [1,1], target = 2 输出: 1 解释: 1 + 1 = 2

  • 代码:

image.png

11. 盛最多水的容器

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/co…

image.png

  • 方法:
    • 两个指针,左右两边往中间走;
  • 思路:
    • 左右最低高度*宽度=面积,对于高的高度来说,矮的高度决定面积的高度,因此如果是矮的就走下一个,高的保持不动就可以确保得到面积的最大值。
  • 代码: image.png

382. 三角形计数

给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形? 样例 样例 1: 输入: [3, 4, 6, 7] 输出: 3 解释: 可以组成的是 (3, 4, 6), (3, 6, 7), (4, 6, 7) 样例 2: 输入: [4, 4, 4, 4] 输出: 4 解释: 任何三个数都可以构成三角形 所以答案为 C(3, 4) = 4 输入测试数据 (每行一个参数)如何理解测试数据?

  • 证明:“较小两值之和>最大值”是形成三角形的充要条件。
  • 代码:固定最大值,求前面两个较小值的和小于这个最大值 a<b<c => 求a+b < c如果找到了,那么a-b之间的a,a1,a2,a3…b…c=> ai+b>c因此,数目是a-b之间的所有数的个数.

image.png

42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 示例 2:

输入:height = [4,2,0,3,2,5] 输出:9 提示:

n == height.length 0 <= n <= 3 * 104 0 <= height[i] <= 105

  • 思路:
    • 某个点的储水面积=左右两边最高点的低点-当前高度* 宽度
    • 1、暴力解法:每个点最左边的最高点,和往右的最高点都算出来,然后再计算每个点的面积;
    • 2、双指针解法:左右指针相向走。
  • 代码:

image.png

15. 3Sum

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Notice that the solution set must not contain duplicate triplets.

  • 方法:两个数的和时用双指针:两边向中间扫描。
  • 代码:

image.png

16. 最接近的三数之和

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

  • 方法:
    • 两个数的和时,双指针:两边超中间扫描
  • 代码:

image.png

345. 反转字符串中的元音字母

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。 示例 1:

输入:"hello" 输出:"holle" 示例 2:

输入:"leetcode" 输出:"leotcede"

  • 类型归类:指针相对运动。
  • 分析:双指针,相对运动。扫描左右等于元音的就替换。
  • 代码: image.png

80. 删除有序数组中的重复项 II

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); }

示例 1:

输入:nums = [1,1,1,2,2,3] 输出:5, nums = [1,1,2,2,3] 解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。 示例 2:

输入:nums = [0,0,1,1,1,1,2,3,3] 输出:7, nums = [0,0,1,1,2,3,3] 解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。

  • 类型归类:指针同向运动。
  • 方法1: 提取特征:有序,返回数组最后的长度。
  • 1、 最多重复一次,因此必然:I > I -2
  • 2、 固定数组赋值指针
  • 3、 另一个数是赋值给数组的数:如何得到?如果数组这个值>数组中的i-2的值就可以赋值给它了,如果不是就下一个数即可。

image.png

  • 方法2:

image.png