📣 VIP通行证夏日特惠 限时立减$68
查看: 13563| 回复: 22
跳转到指定楼层
上一主题 下一主题
收起左侧

求解3Sum without sort,O(n^2)

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
看到FB的followup,喜欢问,请问有什么思路吗?


上一篇:FB面试题-校园版第一批
下一篇:有没有推荐的C++的英文公开课
推荐
JimmyZhuang 2016-9-15 00:57:47 | 只看该作者
全局:
关键是怎么避免重复,楼主可以尝试用map[nums[i], count]记录frequency,然后把map里所有的key放在一个vector里,重复的会连在一起,这样就可以避免重复了
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        if(nums.size() < 3) return res;
        unordered_map<int, int> mp;
        for(int i : nums)
            mp[i]++;
        vector<int> arr(nums.size());
        int k = 0;
        for(auto& it : mp) {
            for(int i = 0; i < it.second; i++) {
                arr[k++] = it.first;
            }
        }
        
        vector<int> tmp;
        for(int i = 0; i <= arr.size() - 3; i++) {
            if(i != 0 && arr[i] == arr[i - 1]) continue;
            tmp.push_back(arr[i]);
            twoSum(arr, i + 1, arr.size() - 1, tmp, res, -arr[i]);
            tmp.pop_back();
        }
        return res;
    }
private:
    void twoSum(vector<int>& arr, int start, int end, vector<int>& tmp, vector<vector<int>>& res, int target) {
        unordered_set<int> st;
        unordered_set<int> visited;
        
        for(int i = start; i <= end; i++) {
            if(st.find(target - arr[i]) != st.end() && visited.find(target - arr[i]) == visited.end()) {
                tmp.push_back(target - arr[i]);
                tmp.push_back(arr[i]);
                res.push_back(tmp);
                tmp.pop_back();
                tmp.pop_back();
                visited.insert(arr[i]);
                visited.insert(target - arr[i]);
            }
            st.insert(arr[i]);
        }
    }
};
回复

使用道具 举报

推荐
e5399014 2017-11-8 05:50:52 | 只看该作者
全局:
本帖最后由 e5399014 于 2017-11-8 05:55 编辑

O(N^2) 最坏情况[0,0,0,0,0] 是O(N^3)
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i ++) {
            map.put(nums, i);
        }
        for (int i = 0; i < nums.length-1; i ++) {
            for (int j = i+1; j < nums.length; j ++) {
                if (map.containsKey(-nums[i]-nums[j])) {
                    if (map.get(-nums[i]-nums[j]) > j) {
                        ArrayList<Integer> a = new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[map.get(-nums[i]-nums[j])]));
                        Collections.sort(a);
                        res.add(a);
                    }
                }
            }
        }
        res = res.stream().distinct().collect(Collectors.toList());
        return res;
    }
}
[/i][/i][/i][/i]
回复

使用道具 举报

推荐
iPhD 2016-9-14 11:28:56 | 只看该作者
全局:
hkc593 发表于 2016-9-14 11:03
怎么处理[-1,-1, 2]能

这不是能正常处理吗?两层loop,找到-1,-1时,发现2在map里并且2的index = 2比前两个都要大,存下这个结果。
回复

使用道具 举报

🔗
tamitito 2016-9-14 03:25:51 | 只看该作者
全局:
用2Sum without sort做,外层套个循环就是了
回复

使用道具 举报

🔗
iPhD 2016-9-14 03:38:13 | 只看该作者
全局:
就用HashMap存<num, index>就行了,然后用两层loop,在Map里找target - num1 - num2的值并且index > i1 && index >2
回复

使用道具 举报

🔗
ytsr 2016-9-14 03:39:05 | 只看该作者
全局:
不sort就hash
回复

使用道具 举报

🔗
zzgzzm 2016-9-14 10:37:09 | 只看该作者
全局:
Since it does not allow to sort the array, I assume it only asks for one triplet as solution or returns an empty triplet if no such sum exists. Also, I don't think using Hash map to store value to index works since the given array could have duplicates. I would recommend to use Hash map to store value to frequency.

  1. vector<int> find3Sum(vector<int>& a, int target)  {
  2.   int n = a.size();
  3.   if (n < 3) return vector<int>();
  4.   unordered_map<int,int> freq;
  5.   for (auto& x:a) freq[x]++;
  6.   for (int i = 0; i < n-1; i++) {
  7.     for (int j = i+1; j < n; j++) {
  8.       int residual = target - a[i] - a[j];
  9.       if (freq.count(residual)) {
  10.         int duplicity = 0;
  11.         if (residual == a[i]) duplicity++;
  12.         if (residual == a[j]) duplicity++;
  13.         if (freq[residual] > duplicity) return {a[i], a[j], residual};
  14.       }
  15.     }
  16.   }  
  17.   return vector<int>();
  18. }
复制代码
回复

使用道具 举报

🔗
citynart 2016-9-14 11:00:28 | 只看该作者
全局:
Two sum hashes O(n) + for loop
回复

使用道具 举报

🔗
 楼主| hkc593 2016-9-14 11:03:31 | 只看该作者
全局:
iPhD 发表于 2016-9-14 03:38
就用HashMap存就行了,然后用两层loop,在Map里找target - num1 - num2的值并且index > i1 && index >2

怎么处理[-1,-1, 2]能
回复

使用道具 举报

🔗
 楼主| hkc593 2016-9-14 11:04:15 | 只看该作者
全局:
zzgzzm 发表于 2016-9-14 10:37
Since it does not allow to sort the array, I assume it only asks for one triplet as solution or retu ...

既然是3sum的follow up,我想应该是写成和3sum同样的结果吧。
回复

使用道具 举报

🔗
JimmyZhuang 2016-9-14 13:03:59 | 只看该作者
全局:
iPhD 发表于 2016-9-14 03:38
就用HashMap存就行了,然后用两层loop,在Map里找target - num1 - num2的值并且index > i1 && index >2

[-4,-2,1,-5,-4,-4,4,-2,0,4,0,-2,3,1,-5,0], 按照你的方法好像会出现[1, 4, -5]和[4, 1 ,-5]这种重复的情况
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

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