每天几题leetcode第一天
作者:互联网
每天leetcode
| 开始刷题计划,每天刷几道,目标一千道,从今天开始,从不断更
时间 2021年9-30
/**
* @author js1981725869@163.com
* @date 2021年09月29日 21:23
*/
import java.util.*;
/**
* 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a ,b ,c ,使得 a + b + c = 0 ?请找出所有和为 0 且 不重复 的三元组。
* <p>
*
* <p>
* 示例 1:
* <p>
* 输入:nums = [-1,0,1,2,-1,-4]
* 输出:[[-1,-1,2],[-1,0,1]]
* 示例 2:
* <p>
* 输入:nums = []
* 输出:[]
* 示例 3:
* <p>
* 输入:nums = [0]
* 输出:[]
* <p>
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/1fGaJU
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class ThreeNumAddToZero {
public static void main(String[] args) {
System.out.println(threeSum(new int[]{-1,0,1,2,-1,-4}));
}
public static List<List<Integer>> threeSum(int[] nums) {
//排序再相加
quickSort(nums, 0, nums.length - 1);
Set<List<Integer>> set = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
int target = -nums[i];
//再i+1到length-1的范围找到两个数相加等于target
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == target) {
set.add(Arrays.asList(nums[i], nums[left], nums[right]));
left++;
right--;
}
else if (sum < target) {
left++;
} else {
right--;
}
}
}
return new ArrayList<>(set); // O(n)
}
//快速排序
public static void quickSort(int[] nums, int left, int right) {
if (nums == null || nums.length == 0) {
return;
}
if (left > right) {
return;
}
int key = nums[right];
//保留left和right的指针位置
int l = left;
int r = right;
/**
* 先移动右边找到比key小的数,在移动左边找到比key大的数,交换(如果不按照这个规则来的话)
* 以下分为两种情况:
*
* 第一种:比如先移动右边找比key大的数,再移动左边找比key小的数,那么右边的移动其实没有必要,
* 因为我们就是从左往右依次增大,而移动左边找到比key小的数之后就需要跟key交换,
* 这就变成冒泡排序了
*
* 第二种情况如果先移动左边的找到比key大的数,再移动右边找到比左边小的数交换,这样的话,
* 到了最后肯定是先找到左边的最大然后和key做交换,那么就会出错,除非一开始把分界值放在最右侧,
* 那我们使用这一种方式去做快排
*/
while (l != r) {
//l!=r的时候我们就可以根据上面的规则把这两个交换
while (nums[l] <= key && l < r) {
//从左边移动找到大于key的数,当他小于key时,我们把l向右移
l++;
}
while (nums[r] >= key && r > l) {
//从右边开始移动找到小于key的数,当他大于key时,我们把r向左移
r--;
}
//移动完了,看看l和r的情况,只可能是l<r,或者l=r
if (l < r) {
//交换l和r位置的数字
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
}
}
//当l = r的时候我们就把key和这个索引处数字交换
nums[right] = nums[l];
nums[l] = key;
quickSort(nums, left, l - 1);
// [-4, -29, -1, 2, -1, 1, 9, 1, 20, 0]
quickSort(nums, l + 1, right);
}
}
心得:对快速排序有了一定的理解。加油!
标签:right,第一天,nums,int,key,几题,移动,leetcode,left 来源: https://www.cnblogs.com/js119/p/15357896.html