zoukankan      html  css  js  c++  java
  • 【JAVA、C++】LeetCode 015 3Sum

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

    Note:

    • Elements in a triplet (a,b,c) must be in non-descending order. (ie, abc)
    • The solution set must not contain duplicate triplets.
        For example, given array S = {-1 0 1 2 -1 -4},
    
        A solution set is:
        (-1, 0, 1)
        (-1, -1, 2)
    

    解题思路:

    3Sum对初学者估计是丈二和尚摸不着头脑,其实NSum都有固定的解法。参考链接:

    http://tech-wonderland.net/blog/summary-of-ksum-problems.html

    基本上所有思路都是排序后查找,防止出现List的重复,因此想到使用set类型,JAVA实现如下:

    static public List<List<Integer>> threeSum(int[] num) {
    		LinkedHashSet<List<Integer>> set = new LinkedHashSet<List<Integer>>();
    		if (num.length <= 2)
    			return new ArrayList<List<Integer>>(set);
    		final int tar = 0;
    		Arrays.sort(num);
    		for (int i = 0; i < num.length - 2; i++) {
    			int j = i + 1, k = num.length - 1;
    			while (j < k) {
    				if (num[i] + num[j] + num[k] < tar)
    					j++;
    				else if (num[i] + num[j] + num[k] > tar)
    					k--;
    				else {
    					set.add(Arrays.asList(num[i], num[j], num[k]));
    					j++;
    					k--;
    				}
    			}
    		}
    		return new ArrayList<List<Integer>>(set);
    	}
    

     结果第一次提交Time Limit Exceeded,第二次提交竟然神奇般的通过了!!!时间425ms,估计也是擦线飘过。

     原因在于set每添加一个元素都会和set中元素进行比较,也就是说需要一次遍历,这样每添加一个元素,时间开销就会比较大,因此修改代码如下,时间322 ms:

    static public List<List<Integer>> threeSum(int[] num) {
        ArrayList<List<Integer>> list = new ArrayList<List<Integer>>();
    		final int tar = 0;
    		Arrays.sort(num);
    		for (int i = 0; i < num.length - 2; i++) {
    			int j = i + 1, k = num.length - 1;
    			while(i < k && num[i]==num[i+1])
    				i++;
    			while (j < k) {
    				if (num[i] + num[j] + num[k] < tar)
    					j++;
    				else if (num[i] + num[j] + num[k] > tar)
    					k--;
    				else {
    					list.add(Arrays.asList(num[i], num[j], num[k]));
    					j++;
    					k--;
    					while(j<k&&num[j]==num[j-1])
    						j++;
    					while(k>j&&num[k]==num[k+1])
    						k--;
    				}
    			}
    		}
    		return list;
    	}
    

     C++:

     1 class Solution {
     2 public:
     3     vector<vector<int>> threeSum(vector<int>& nums) {
     4         vector<vector<int>> res;
     5         if (nums.size() <= 2)
     6             return res;
     7         const int tar = 0;
     8         sort(nums.begin(),nums.end());
     9         for (int i = 0; i < nums.size() - 2; i++) {
    10             int j = i + 1, k = nums.size() - 1;
    11             while (i < k && nums[i] == nums[i + 1])
    12                 i++;
    13             while (j < k) {
    14                 if (nums[i] + nums[j] + nums[k] < tar)
    15                     j++;
    16                 else if (nums[i] + nums[j] + nums[k] > tar)
    17                     k--;
    18                 else {
    19                     res.push_back({ nums[i], nums[j], nums[k]});
    20                     j++;
    21                     k--;
    22                     while (j<k&&nums[j] == nums[j - 1])
    23                         j++;
    24                     while (k>j&&nums[k] == nums[k + 1])
    25                         k--;
    26                 }
    27             }
    28         }
    29         return res;
    30     }
    31 };
  • 相关阅读:
    unicode 转换成中文
    iOS开发中UILocalNotification本地通知实现简单的提醒功能
    Xcode8出现AQDefaultDevice (173): skipping input stream 0 0 0x0
    UITextView回收或关闭键盘
    2016最新cocoapods安装流程,安装过程中遇到的问题及解决方法
    Android将应用调试log信息保存在SD卡
    Android 防止控件被重复点击
    android TextView多行文本(超过3行)使用ellipsize="end"属性无效问题的解决方法
    Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点
    Android Touch事件传递机制 一: OnTouch,OnItemClick(监听器),dispatchTouchEvent(伪生命周期)
  • 原文地址:https://www.cnblogs.com/tonyluis/p/4465366.html
Copyright © 2011-2022 走看看