Two pointer 专题01
分类:
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.
- 特点:有序数组,寻找满足一定条件的一个状态。
- 代码:
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
- 代码:
11. 盛最多水的容器
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/co…
- 方法:
- 两个指针,左右两边往中间走;
- 思路:
- 左右最低高度*宽度=面积,对于高的高度来说,矮的高度决定面积的高度,因此如果是矮的就走下一个,高的保持不动就可以确保得到面积的最大值。
- 代码:
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之间的所有数的个数.
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、双指针解法:左右指针相向走。
- 代码:
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.
- 方法:两个数的和时用双指针:两边向中间扫描。
- 代码:
16. 最接近的三数之和
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
- 方法:
- 两个数的和时,双指针:两边超中间扫描
- 代码:
345. 反转字符串中的元音字母
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。 示例 1:
输入:"hello" 输出:"holle" 示例 2:
输入:"leetcode" 输出:"leotcede"
- 类型归类:指针相对运动。
- 分析:双指针,相对运动。扫描左右等于元音的就替换。
- 代码:
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的值就可以赋值给它了,如果不是就下一个数即可。
- 方法2: