标签:.so print 左移 else new 指针 数组排序 import 结果
1 package threesum; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.List; 6 7 /** 8 * 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 9 * 注意:答案中不可以包含重复的三元组 10 * 11 * 主要的思想:如果采用暴力法的话,时间复杂度很高出现超时的情况。 12 * 对暴力法进行一系列的改进 先从数组的开始取出元素,在剩下的数中设置首尾指针, 通过首尾指针的移动来遍历其中所有的数字。 13 * 具体的细节问题 会通过代码注释的方式进行记录 14 * @author Saint 15 * 16 */ 17 18 public class Solution { 19 public static void main(String[] args) { 20 int[] nums = {-1,0,1,2,-1,-4}; 21 ArrayList<List<Integer>> answers = new ArrayList<List<Integer>>(); 22 answers = (ArrayList<List<Integer>>) threeSum(nums); 23 for (List<Integer> list : answers) { 24 System.out.println(list); 25 } 26 } 27 28 public static List<List<Integer>> threeSum(int[] nums) { 29 /* 30 * 不能使用ArrayList对其中重复的数值进行去重 31 */ 32 /* 33 * ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i 34 * < nums.length; i++) { list.add(nums[i]); } 35 */ 36 ArrayList<List<Integer>> answers = new ArrayList<List<Integer>>(); 37 /* 38 * 对数组进行排序,后面会进行说明 39 */ 40 Arrays.sort(nums); 41 for (int i = 0; i < nums.length; i++) { 42 System.out.println(i); 43 /* 44 * 设置首尾指针 left与right不能重合 45 */ 46 for (int left = i + 1, right = nums.length - 1, num = nums[i]; left < right;) { 47 System.out.println(num + " " + nums[left] + " " + nums[right]); 48 49 if (num + nums[left] + nums[right] == 0) { 50 System.out.println("equal"); 51 ArrayList<Integer> temp = new ArrayList<Integer>(); 52 temp.add(num); 53 temp.add(nums[left]); 54 temp.add(nums[right]); 55 answers.add(temp); 56 /* 57 * 如果相同,添加到集合中,同时首尾指针需要跳过当前的位置 58 */ 59 left = moveLeft(nums, left, right); 60 right = moveRight(nums, left, right); 61 /* 62 * 通过之前的数组排序,数组从大到小排列 例如:5 4 3 2 1 63 * 当首尾指针两数之和大于nums[i]时, 需要减小数字 left++或者right-- 对应数组就会变小(显然不可能) 64 * 这一点是我觉得比较精妙的一点 首尾移动需要遍历出所有的情况 不能像我之前想法 左移动一个 右移动一个 65 * 通过暴力的方法更不推荐 66 */ 67 } else if (nums[left] + nums[right] > 0) { 68 left = moveLeft(nums, left, right); 69 } else { 70 right = moveRight(nums, left, right); 71 } 72 } 73 } 74 return answers; 75 } 76 /** 77 * 取出重复的数字 例如:1 1 -2 -2 -2这个数组 78 * 当三数之和相等时,left=1 right=4 这时需要left++ right-- 跳过当前位置同时检查下个位置是否和前一个位置是否为相同 79 * right=3和之前的数字相同 继续right--知道nums[right]不和之前数字相同 80 * 之后执行到left = right 循环结束返回结果 for循环不成立 结束整个过程 81 * @param nums 82 * @param left 83 * @param right 84 * @return 85 */ 86 public static int moveLeft(int[] nums, int left, int right) { 87 int num = nums[left++]; 88 while (left <= right) { 89 if (nums[left] != num) 90 break; 91 left++; 92 } 93 return left; 94 95 } 96 97 public static int moveRight(int[] nums, int left, int right) { 98 int num = nums[right--]; 99 while (left <= right) { 100 if (nums[right] != num) 101 break; 102 right--; 103 } 104 return right; 105 106 } 107 }
标签:.so print 左移 else new 指针 数组排序 import 结果
原文地址:https://www.cnblogs.com/relaxxx/p/10432163.html