zoukankan      html  css  js  c++  java
  • LeetCode:15. 3Sum(Medium)

    1. 原题链接

    https://leetcode.com/problems/3sum/description/

    2. 题目要求

    数组S = nums[n]包含n个整数,请问S中是否存在a,b,c三个整数,使得a+b+c=0。找出所有满足该条件的三元组,且不包含重复三元组。

    3. 解题思路

    首先对数组进行排序

    思路一:三层for循环暴力解决,同时考虑过滤重复,时间复杂度为O(n3)

    思路二:时间复杂度为O(n2),外面一层for循环,以每个元素 nums[i] 作为三元组重的一个元素,然后从剩余的元素中找出二者之和满足0-nums[i]的两个元素。通过一层while循环,从剩余所有元素的首位两个元素开始找,不断向中间逼近。

    过滤重复:因为已经对数组进行排序,所以相同的整数一定会连在一起。当使用for循环进行遍历时,如果当前指向元素 nums[i] 与 nums[i-1]相同,则可跳出本次循环,执行 i++,从而达到过滤重复的目的。

    4. 代码实现

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.List;
    
    public class ThreeSum15 {
        public static void main(String[] args) {
            int[] nums = {-5, -2, -2, -2, -4, 4, 0, 5};
            for (int i = 0; i < ThreeSum15.threeSum(nums).toArray().length; i++) {
                System.out.println(ThreeSum15.threeSum(nums).get(i));
            }
        }
    
        public static List<List<Integer>> threeSum(int[] nums) {
            Arrays.sort(nums);
            List<List<Integer>> ls = new LinkedList<>();
    
            for (int i = 0; i < nums.length - 2; i++) {
                if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) {  // 跳过可能重复的答案
    
                    int l = i + 1, r = nums.length - 1, sum = 0 - nums[i];
                    while (l < r) {
                        if (nums[l] + nums[r] == sum) {
                            ls.add(Arrays.asList(nums[i], nums[l], nums[r]));
                            while (l < r && nums[l] == nums[l + 1]) l++;
                            while (l < r && nums[r] == nums[r - 1]) r--;
                            l++;
                            r--;
                        } else if (nums[l] + nums[r] < sum) {
                            while (l < r && nums[l] == nums[l + 1]) l++;   // 跳过重复值
                            l++;
                        } else {
                            while (l < r && nums[r] == nums[r - 1]) r--;
                            r--;
                        }
                    }
                }
            }
            return ls;
        }
    }
    

      

  • 相关阅读:
    20111013 18:32 女友刁钻无聊问题之标准答案
    20111013 17:40 学ACM有什么用
    typedef用法(1)
    深入C++的new(20111115 15:08 )
    用四个0算二十四点
    20111010 20:14 HDU 4021 (15数码)
    pku3020 Antenna Placement (解法1)
    C++箴言:理解typename的两个含义
    20110907 00:16 ubuntu 如何修改当前用户名
    vc6.0中添加msdn 20111105 11:52
  • 原文地址:https://www.cnblogs.com/huiAlex/p/8078911.html
Copyright © 2011-2022 走看看