leetCode:三数之和

打印 上一主题 下一主题

主题 906|帖子 906|积分 2718

题目:
给你一个整数数组 nums ,判断是否存在三元组 [nums, nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums + nums[j] + nums[k] == 0 。请你返回全部和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解题思绪历程:
  1. 第一个想到的方法三个循环,第一个循环从数组的0索引(i)位置开始,第二个循环从数组的j(i+1)索引位置开始,第三个循环从数组的m(i+1+1)位置开始,然后输出nums[i]+nums[j]+nums[m] == 0的结果,但是这种做法会出现重复的三元组元素。如果需要去除这些重复元素,则需要再一次便历,这样算法的效率会大大降低,所以果断去除这种方式。所以在这种方式之后,我想如果把原始数组先排序,然后将排序之后的数组进行三重循环,每一层循环加一个if判断条件,如果当前位置元素与上一个位置元素的值相等,第一层循环的时候需要i>.0,第二重循环需要j-i>1,第三重循环需要m-j>1,这样输出的元素数组就不会再重复,此时算法的时间复杂度是O(N^3),但是如果使用双指针,这个算法会不会可以优化?
  2. O(N^3)代码:
  3. Arrays.sort(nums);
  4.     System.out.println(Arrays.toString(nums));
  5.     if (nums.length < 3) {
  6.         return null;
  7.     }
  8.     int sum = 0;
  9.     List<List<Integer>> lists = new ArrayList<>();
  10.     List<Integer> inList = new ArrayList<>();
  11.     if (nums.length == 3) {
  12.         sum = nums[0] + nums[1] + nums[2];
  13.         if (sum == 0) {
  14.             inList.add(nums[0]);
  15.             inList.add(nums[1]);
  16.             inList.add(nums[2]);
  17.             lists.add(inList);
  18.         }
  19.         return lists;
  20.     }
  21.     for (int i = 0; i < nums.length - 2; i++) {
  22.         if (i > 0 && nums[i] == nums[i - 1]) {
  23.             continue;
  24.         }
  25.         for (int right = i + 1; right < nums.length - 1; right++) {
  26.             if(nums[right] == nums[right - 1] && right - i > 1){
  27.                 continue;
  28.             }
  29.             int temp = right + 1;
  30.             while(temp <= nums.length-1){
  31.                 if(nums[temp] == nums[temp - 1] && temp - right > 1){
  32.                     ++temp;
  33.                     continue;
  34.                 }
  35.                 inList = new ArrayList<>() ;
  36.                 if (nums[i] + nums[right] + nums[temp] == 0) {
  37.                     inList.add(nums[i]);
  38.                     inList.add(nums[right]);
  39.                     inList.add(nums[temp]);
  40.                     lists.add(inList);
  41.                 }
  42.                 temp++;
  43.             }
  44.         }
  45.     }
  46.     return lists;
  47. }
复制代码
  1. 第二种方法:维持前两个循环不变,在第二个循环上添加一个指针,并且得到目标值是-nums[i],这个指针从nums[]的末端开始前移,如果移动到跟第二个循环变量j相等,则直接跳出循环,指针前移的条件是m>j,nums[j] + nums[m] >
  2. -nums[i],最后将nums[j] + nums[m] == -nums[i]的索引存入新的集合中,然后将该集合添加至要返回的集合中并返回,此时算法的时间复杂度是O(N^2)
  3. O(N^2)代码:
  4. public static List<List<Integer>> secondThreeSum(int[] nums) {
  5.     nums = Arrays.stream(nums).sorted().toArray();
  6.     Arrays.sort(nums);
  7.     System.out.println(Arrays.toString(nums));
  8.     if (nums.length < 3) {
  9.         return null;
  10.     }
  11.     int sum = 0;
  12.     List<List<Integer>> lists = new ArrayList<>();
  13.     List<Integer> inList = new ArrayList<>();
  14.     if (nums.length == 3) {
  15.         sum = nums[0] + nums[1] + nums[2];
  16.         if (sum == 0) {
  17.             inList.add(nums[0]);
  18.             inList.add(nums[1]);
  19.             inList.add(nums[2]);
  20.             lists.add(inList);
  21.         }
  22.         return lists;
  23.     }
  24.     for (int i = 0; i < nums.length - 2; i++) {
  25.         if (i > 0 && nums[i] == nums[i - 1]) {
  26.             continue;
  27.         }
  28.         int target = -nums[i];
  29.         int temp = nums.length - 1;
  30.         for (int right = i + 1; right < nums.length - 1; right++) {
  31.             if(nums[right] == nums[right - 1] && right - i > 1){
  32.                 continue;
  33.             }
  34.             while((nums[right] + nums[temp]) > target && temp > right) {
  35.                 --temp;
  36.             }
  37.             if(temp == right){
  38.                 break;
  39.             }
  40.             inList = new ArrayList<>() ;
  41.             if (nums[right] + nums[temp] == target) {
  42.                 inList.add(nums[i]);
  43.                 inList.add(nums[right]);
  44.                 inList.add(nums[temp]);
  45.                 lists.add(inList);
  46.             }
  47.         }
  48.     }
  49.     return lists;
  50. }
复制代码
  1.  
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

麻花痒

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表