1. 盛最多水的容器
题目描述
解题思路
初始两个指针,一个指向数组第一个元素,一个指向数组最后一个元素,两个指针相隔的区间就可以看作是盛水的容量,当然还会由两个指针指向的较小的数来决定。
之后,每次我们移动指向的较小值的指针,并且计算其容量,最终可得出能容纳水的最大值。
public int maxArea(int[] height) {
int left = 0, right = height.length - 1;
int ans = 0;
while(left < right){
ans = Math.max(ans, Math.min(height[left], height[right]) * (right - left));
if(height[left] < height[right]){
left++;
}else{
right--;
}
}
return ans;
}
2. 删除有序数组中的重复项
解题思路
初始两个指针,全部指向数组第一个元素,一个指针用来表示当前不重复值的最后一个位置,一个指针通过向右移动,寻找不重复的值。
public int removeDuplicates(int[] nums) {
int p1 = 0, p2 = 0;
int len = nums.length;
while(p2 < len){
// 如果不相等,则表示找到了不重复的值
if(nums[p1] != nums[p2]){
// 不重复位置向右移一下
p1++;
// 通过交换,把不重复的值保留下来
swap(nums, p1, p2);
}
// 不断向右移动,寻找不重复的值
p2++;
}
return p1 + 1;
}
public void swap(int[] nums, int p1, int p2){
int temp = nums[p1];
nums[p1] = nums[p2];
nums[p2] = temp;
}
3. 移除元素
解题思路
同上一题一致,指针p1
寻找要删除的值的下标,指针p2
不断的向右移动,只要发现当前值不等于val
就与p1
指向的下标交换
public int removeElement(int[] nums, int val) {
int p1 = 0, p2 = 0;
int len = nums.length;
while(p2 < len){
if(nums[p2] != val){
swap(nums, p1, p2);
p1++;
}
p2++;
}
return p1;
}
public void swap(int[] nums, int p1, int p2){
int temp = nums[p1];
nums[p1] = nums[p2];
nums[p2] = temp;
}
4. 颜色分类
解题思路
一道经典的【荷兰国旗问题】,快排中的子过程。
public void sortColors(int[] nums) {
// 两个指针初始下标都为0
int p0 = 0, p1 = 0;
int len = nums.length;
for(int i = 0; i<len; i++){
if (nums[i] == 0){
// 如果找到0,则交换0的位置
swap(nums, p0, i);
// 如果指向0的位置,小于指向1的位置,则swap(nums, p0, i)交换,会把1交换到i的位置上,所以i要再与p1交换一次
if(p0 < p1){
swap(nums, p1, i);
}
// 最后p0和p1都移动一位
p0++;
p1++;
} else if(nums[i] == 1){
// 如果找到1,则交换1的位置,并把p1移动一位
swap(nums, p1, i);
p1++;
}
}
}
public void swap(int[] nums, int p, int i){
int temp = nums[p];
nums[p] = nums[i];
nums[i] = temp;
}
5. 三数之和
解题思路
排序+双指针
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
List<List<Integer>> ans = new ArrayList<>();
for(int i = 0; i < n; i++){
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
int target = -nums[i];
int k = n - 1;
for(int j = i + 1; j < n; j++){
if(j > i + 1 && nums[j] == nums[j-1]){
continue;
}
while(j < k && nums[j] + nums[k] > target){
k--;
}
if(j == k){
continue;
}
if(nums[j] + nums[k] == target){
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
ans.add(list);
}
}
}
return ans;
}