15.三数之和——LeetCode

Posted relaxxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了15.三数之和——LeetCode相关的知识,希望对你有一定的参考价值。

技术图片

  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 }

 

以上是关于15.三数之和——LeetCode的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode15.三数之和(C++,Python)

LeetCode15.三数之和(C++,Python)

leetcode(15)三数之和+去重

LeetCode1两数之和15三数之和

LeetCode1两数之和15三数之和

LeetCode刷题15-简单-三数之和