Merge branch 'master' of https://gitee.com/dingjiawen/self_example
This commit is contained in:
commit
b3c7303820
|
|
@ -0,0 +1,162 @@
|
||||||
|
package sort;
|
||||||
|
|
||||||
|
import com.sun.corba.se.impl.ior.FreezableList;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 三数之和
|
||||||
|
* 给你一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c ,使得a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组
|
||||||
|
* <p>
|
||||||
|
* 思路:
|
||||||
|
* 「不重复」的本质是什么?我们保持三重循环的大框架不变,只需要保证:
|
||||||
|
* 第二重循环枚举到的元素不小于当前第一重循环枚举到的元素;
|
||||||
|
* 第三重循环枚举到的元素不小于当前第二重循环枚举到的元素。
|
||||||
|
* <p>
|
||||||
|
* 也就是说,我们枚举的三元组 (a, b, c) 满足 a≤b≤c,保证了只有 (a,b,c) 这个顺序会被枚举到,而 (b,a,c)、(c,b,a) 等等这些不会
|
||||||
|
* 这样就减少了重复。要实现这一点,我们可以将数组中的元素从小到大进行排序,随后使用普通的三重循环就可以满足上面的要求。
|
||||||
|
* <p>
|
||||||
|
* 使用双指针让时间复杂度变为O(n^2)
|
||||||
|
*/
|
||||||
|
public class ThreeSum {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
int[] nums = {-1, 0, 1, 2, -1, -4};
|
||||||
|
|
||||||
|
List<List<Integer>> result = threeSum(nums);
|
||||||
|
|
||||||
|
System.out.println(result);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<List<Integer>> threeSum(int[] nums) {
|
||||||
|
|
||||||
|
List<List<Integer>> parentList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (nums.length < 3) {
|
||||||
|
return parentList;
|
||||||
|
}
|
||||||
|
//先排序
|
||||||
|
Arrays.sort(nums);
|
||||||
|
|
||||||
|
//后累加
|
||||||
|
//第一个数的索引i
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
|
||||||
|
if(nums[i]>0) break;
|
||||||
|
|
||||||
|
//为了避免这一次和前一次重复
|
||||||
|
if (i > 0 && nums[i] == nums[i - 1]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//第三个数的索引k
|
||||||
|
int k = nums.length - 1;
|
||||||
|
|
||||||
|
//所需要的第二个数和第三个数之和
|
||||||
|
int need = -nums[i];
|
||||||
|
|
||||||
|
//第二个数的索引j
|
||||||
|
for (int j = i + 1; j < nums.length; j++) {
|
||||||
|
//为了避免这一次和前一次重复
|
||||||
|
if (j > i + 1 && nums[j] == nums[j - 1]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (j < k && nums[j] + nums[k] > need) {
|
||||||
|
k--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断是通过什么条件出来的,如果是第一个条件,就证明这个j不合适,反之就合适,是需要的数
|
||||||
|
if (j == k) {
|
||||||
|
//这里直接break而不是continue,因为如果这个数加上后面的数都大于need,那后面的循环没有必要了
|
||||||
|
// 后面的循环一定比这次的还有大
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//如果是第二个条件跳出的循环
|
||||||
|
if (nums[j] + nums[k] == need) {
|
||||||
|
List<Integer> list = new ArrayList<>();
|
||||||
|
list.add(nums[i]);
|
||||||
|
list.add(nums[j]);
|
||||||
|
list.add(nums[k]);
|
||||||
|
parentList.add(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return parentList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//更简洁一点的思路
|
||||||
|
public static List<List<Integer>> threeSum1(int[] nums) {
|
||||||
|
|
||||||
|
List<List<Integer>> parentList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (nums.length < 3) {
|
||||||
|
return parentList;
|
||||||
|
}
|
||||||
|
//先排序
|
||||||
|
Arrays.sort(nums);
|
||||||
|
|
||||||
|
//后累加
|
||||||
|
//第一个数的索引i
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
|
||||||
|
if(nums[i]>0) break;
|
||||||
|
|
||||||
|
//为了避免这一次和前一次重复
|
||||||
|
if (i > 0 && nums[i] == nums[i - 1]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//第三个数的索引k
|
||||||
|
int k = nums.length - 1;
|
||||||
|
|
||||||
|
//第二个数的索引
|
||||||
|
int j=i+1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//开始遍历
|
||||||
|
while(j<k){
|
||||||
|
//三数之和
|
||||||
|
int sum = nums[i]+nums[j]+nums[k];
|
||||||
|
if(sum<0){
|
||||||
|
//不够了
|
||||||
|
j++;
|
||||||
|
|
||||||
|
}else if(sum>0){
|
||||||
|
//太多了
|
||||||
|
k--;
|
||||||
|
|
||||||
|
}else {
|
||||||
|
parentList.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[j],nums[k])));
|
||||||
|
//为了避免和上一次重复
|
||||||
|
while (j<k&&nums[j+1]==nums[j]){j++;} //相同中间数只能出现一次
|
||||||
|
while (j<k&&nums[k-1]==nums[k]){k--;} //相同最大数只能出现一次
|
||||||
|
j++;
|
||||||
|
k--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return parentList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,8 +7,9 @@ import java.util.List;
|
||||||
|
|
||||||
import static tree.InorderTraversal.inorderTraversal1;
|
import static tree.InorderTraversal.inorderTraversal1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除二叉排序树的某个节点
|
||||||
|
*/
|
||||||
public class DeleteNode {
|
public class DeleteNode {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
@ -94,11 +95,7 @@ public class DeleteNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ import lombok.Data;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中序遍历二叉排序树
|
||||||
|
*/
|
||||||
public class InorderTraversal {
|
public class InorderTraversal {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue