12
返回列表 发新帖
楼主: slightlyOff
跳转到指定楼层
上一主题 下一主题
收起左侧

[数组] 3sum 不sort怎么做?

🔗
jason123 2018-2-2 13:58:24 | 只看该作者
全局:
sizem 发表于 2018-2-2 13:38
求解 什麼是去重?

avoid duplicates in the result

评分

参与人数 1大米 +1 收起 理由
sizem + 1 很有用的信息!

查看全部评分

回复

使用道具 举报

🔗
chenqianhe 2018-9-20 13:57:40 | 只看该作者
全局:
我的想法是这样
遍历数组 对于每个数nums[i] 第二个数nums[j] 必须选大于等于nums[i]且i!=j, 第三个数nums[k]必须比nums[j]大与等于且j!=k, k!=i
这样就不会有重合的 不过time complexity是n三次 空间constant

for loop里面用2sum好像也挺方便的 时间n方 空间要求高 且考虑重复的时候可能会用到sort.
回复

使用道具 举报

🔗
thuxx 2018-11-12 14:02:01 | 只看该作者
全局:
  1. class Solution {
  2.     // 不用排序的版本,超时
  3.     public List<List<Integer>> threeSum(int[] nums) {
  4.         List<List<Integer>> results = new ArrayList<>();

  5.         Set<List<Integer>> set = new HashSet<>();
  6.         Map<Integer, Integer> map = new HashMap<>();
  7.         for (int num : nums) {
  8.             map.put(num, map.getOrDefault(num, 0) + 1);
  9.         }

  10.         for (int i = 0; i < nums.length; i++) {
  11.             // 注意 j 从 0 开始,因为内部还是需要判断升降序来去重,如果从 i + 1 开始可能会漏解
  12.             for (int j = 0; j < nums.length; j++) {
  13.                 int a = nums[i];
  14.                 int b = nums[j];
  15.                 int c = 0 - a - b;
  16.                 // 去重
  17.                 if (!(a >= b && b >= c)) {
  18.                     continue;
  19.                 }

  20.                 if (map.containsKey(c)) {
  21.                     map.put(a, map.get(a) - 1);
  22.                     map.put(b, map.get(b) - 1);
  23.                     map.put(c, map.get(c) - 1);
  24.                 } else {
  25.                     continue;
  26.                 }

  27.                 if (map.get(a) >= 0 && map.get(b) >= 0 && map.get(c) >= 0) {
  28.                     // 去重
  29.                     set.add(Arrays.asList(a, b, c));
  30.                 }

  31.                 map.put(a, map.get(a) + 1);
  32.                 map.put(b, map.get(b) + 1);
  33.                 map.put(c, map.get(c) + 1);
  34.             }
  35.         }

  36.         results.addAll(set);
  37.         return results;
  38.     }
  39. }
复制代码

  1. class Solution {
  2.     // 不用排序的版本,超时
  3.     public List<List<Integer>> threeSum(int[] nums) {
  4.         List<List<Integer>> results = new ArrayList<>();
  5.         Set<List<Integer>> set = new HashSet<>();

  6.         for (int i = 0; i < nums.length; i++) {
  7.             for (int j = 0; j < nums.length; j++) {
  8.                 int a = nums[i];
  9.                 int b = nums[j];
  10.                 int c = 0 - a - b;
  11.                 if (!(a >= b && b >= c)) {
  12.                     continue;
  13.                 }
  14.                 for (int k = 0; k < nums.length; k++) {
  15.                     if (nums[k] == c && i != j && j != k && i != k) {
  16.                         set.add(Arrays.asList(a, b, c));
  17.                     }
  18.                 }
  19.             }
  20.         }

  21.         results.addAll(set);
  22.         return results;
  23.     }
  24. }
复制代码


不排序两个版本均TLE, 前者过了倒数第二个case,最后一个3000个0的case 看脸跑,1200ms-1300ms之间,后者最后两个Case都TLE

评分

参与人数 4大米 +19 收起 理由
liqingfd + 1 很有用的信息!
qaert + 3 给你点个赞!
mierdalol + 10 给你点个赞!
liwenrui2008 + 5 给你点个赞!

查看全部评分

回复

使用道具 举报

🔗
黓龙君 2018-12-25 03:56:20 | 只看该作者
全局:
bunnyNova 发表于 2017-12-21 11:04
这个题我面试的时候被问到了,我说三个数从小到大排,然后存。面试官说我还是sort,不符合要求。于是这轮 ...

刚想到的,存答案的时候可以存两个数,因为是3 sum,存两个数就可以推断出第三个数,存的两个数分别存三个数中的最大值和最小值,这样就可以避免sort了。不过这个面试官到底想考察什么??
回复

使用道具 举报

🔗
shurui91 2019-2-27 22:47:43 | 只看该作者
全局:
黓龙君 发表于 2017-11-7 08:35
为什么你不想sort? 不sort的话brute force,对每一个元素做 two sum就好了。

不sort可以作为这个题的followup
回复

使用道具 举报

全局:
沒 sort 且不超時 (單依然很慢)
  1. class Solution {
  2. public:
  3.     vector<vector<int>> threeSum(vector<int>& nums) {
  4.         unordered_map<int,bool> num1s;
  5.         int zeroCnt=0;
  6.         for(const int num:nums){
  7.             if(!num)zeroCnt++;
  8.             auto it=num1s.find(num);
  9.             if(it==num1s.end())num1s.emplace_hint(it,num,false);
  10.             else it->second=true;
  11.         }
  12.         vector<vector<int>> results;
  13.         for(int i=0;i<nums.size()-2;i++){
  14.             auto it1=num1s.find(nums[i]);
  15.             if(it1==num1s.end()) continue;
  16.             unordered_set<int> num2s(num1s.bucket_count(),num1s.hash_function(),num1s.key_eq());
  17.             for(int j=i+1;j<nums.size()-1;j++){
  18.                 if(nums[i]==0&&nums[j]==0) continue;
  19.                 if(num1s.find(nums[j])==num1s.end()) continue;
  20.                 auto it2=num2s.find(nums[j]);
  21.                 if(it2!=num2s.end()) continue;
  22.                 auto it3=num1s.find(-nums[i]-nums[j]);
  23.                 if(it3!=num1s.end()){
  24.                     if((-nums[i]-nums[j]!=nums[i] &&-nums[i]-nums[j]!=nums[j]) || it3->second) {
  25.                         results.emplace_back(vector<int>{nums[i],nums[j],it3->first});
  26.                         num2s.emplace(it3->first);
  27.                     }
  28.                 }
  29.                 num2s.emplace_hint(it2,nums[j]);
  30.             }
  31.             num1s.erase(it1);
  32.         }
  33.         if(zeroCnt>=3) results.emplace_back(vector<int>{0,0,0});
  34.         return results;
  35.     }
  36. };
复制代码
回复

使用道具 举报

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

本版积分规则

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