• 2017-3-8 leetcode 380 381 532


    l两周以来,第一次睡了个爽,开心!

    =================================

    leetcode380 https://leetcode.com/problems/insert-delete-getrandom-o1/?tab=Description

    leetcode381 https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed/

    leetcode532 https://leetcode.com/problems/k-diff-pairs-in-an-array/?tab=Description

    ====================================================================

    380讲的是
    设计一个数据结构,要求可以在O(1)的时间内完成以下操作
    1,插入一个数字(如果不存在的话)
    2,删除一个数字(如果存在的话)
    3,随机返回一个数字(要求已存在的数字被返回的概率均等)

     我的思路
    一开始其实是一脸懵逼的,后来看了讨论版才明白。。
    如果只有前两个要求,就是普通的hash表,连冲突处理都不需要,加上第三个要求后,要求把数据映射在0——n-1上,那就双向hash好了。。。
    用a数组来存储数据,无序的
    用unordered_map v来存贮数据在a中的下标,可以实现O(1)的数据定位。
    插入简单,删除的时候永远删掉“a中最后的数据”,如果目标数据不是最后的,只需要把它换到最后就好,注意map中存的下标值也随之改变了

     1 class RandomizedSet {
     2 public:
     3     vector<int> a;
     4     unordered_map<int,int> v;
     5     int n;
     6 
     7     /** Initialize your data structure here. */
     8     RandomizedSet() {
     9         a.clear();
    10         v.clear();
    11         srand(time(NULL));
    12         n=0;
    13     }
    14 
    15     /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    16     bool insert(int val) {
    17         if(v.find(val)!=v.end())return false;
    18         a.push_back(val);
    19         v[val]=n++;
    20         return true;
    21     }
    22     /** Removes a value from the set. Returns true if the set contained the specified element. */
    23     bool remove(int val) {
    24         if(v.find(val)==v.end())return false;
    25         unordered_map<int,int>::iterator it=v.find(val);
    26         int ptr=it->second;
    27         if(ptr!=n-1){
    28             v[a[n-1]]=ptr;
    29             a[ptr]=a[n-1];
    30         }
    31         v.erase(it);
    32         a.resize(--n);
    33         return true;
    34     }
    35 
    36     /** Get a random element from the set. */
    37     int getRandom() {
    38         int ptr=rand()%n;
    39         return a[ptr];
    40     }
    41 };
    42 
    43 /**
    44  * Your RandomizedSet object will be instantiated and called as such:
    45  * RandomizedSet obj = new RandomizedSet();
    46  * bool param_1 = obj.insert(val);
    47  * bool param_2 = obj.remove(val);
    48  * int param_3 = obj.getRandom();
    49  */
    380

    ====================================================================

    381讲的是
    设计一个允许重复数据的数据结构,要求可以在O(1)的时间内完成以下操作
    1,插入一个数字(如果存在的话返回false)
    2,删除一个数字(如果存在的话返回true)
    3,随机返回一个数字(要求已存在的数字被返回的概率均等)

    我的思路
    一开始感觉直接直接把380的代码改成multimap就行,结果交了一发发现行不通,a中最后一个数据不知道对应在map中的哪儿(因为可能有多个)
    多个数据的话我们在map中使用vector来存储就可以,为了O(1)定位,我们在a中使用pair来存储val和map第二维的下标
    思考后发现a.back()代表的val一定是相同值最后一次出现的,所以我们只要交换m.find(val).back()和m[a.back().val][a.back().index]就行

     1 class RandomizedCollection {
     2 public:
     3     /** Initialize your data structure here. */
     4     RandomizedCollection() {
     5         
     6     }
     7     
     8     /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
     9     bool insert(int val) {
    10         auto result = m.find(val) == m.end();
    11         
    12         m[val].push_back(nums.size());
    13         nums.push_back(pair<int, int>(val, m[val].size() - 1));
    14         
    15         return result;
    16     }
    17     
    18     /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    19     bool remove(int val) {
    20         auto result = m.find(val) != m.end();
    21         if(result)
    22         {
    23             auto last = nums.back();
    24             m[last.first][last.second] = m[val].back();
    25             nums[m[val].back()] = last;
    26             m[val].pop_back();
    27             if(m[val].empty()) m.erase(val);
    28             nums.pop_back();
    29         }
    30         return result;
    31     }
    32     
    33     /** Get a random element from the collection. */
    34     int getRandom() {
    35         return nums[rand() % nums.size()].first;
    36     }
    37 private:
    38     vector<pair<int, int>> nums;
    39     unordered_map<int, vector<int>> m;
    40 };
    code from the other people
     1 class RandomizedCollection {
     2 private:
     3     vector<pair<int,int>> a;
     4     unordered_map<int,vector<int> > m;
     5     int n;
     6 
     7 public:
     8     /** Initialize your data structure here. */
     9     RandomizedCollection() {
    10         a.clear();
    11         m.clear();
    12         srand(time(NULL));
    13     }
    14 
    15     /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    16     bool insert(int val) {
    17         bool result=(m.find(val)==m.end());
    18         m[val].push_back(a.size());
    19         a.push_back(pair<int,int>(val,m[val].size()-1));
    20         return result;
    21     }
    22 
    23     /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    24     bool remove(int val) {
    25         bool result=(m.find(val)!=m.end());
    26         if(result){
    27             pair<int,int> last=a.back();
    28             if(a.back().first!=val){
    29                 m[last.first][last.second]=m[val].back();
    30                 a[m[val].back()]=a.back();
    31             }
    32             a.pop_back();
    33             m[val].pop_back();
    34             if(m[val].empty())m.erase(val);
    35         }
    36         return result;
    37     }
    38 
    39     /** Get a random element from the collection. */
    40     int getRandom() {
    41         if(!a.size())return -1;
    42         int ptr=rand()%a.size();
    43         return a[ptr].first;
    44     }
    45 };
    46 
    47 /**
    48  * Your RandomizedCollection object will be instantiated and called as such:
    49  * RandomizedCollection obj = new RandomizedCollection();
    50  * bool param_1 = obj.insert(val);
    51  * bool param_2 = obj.remove(val);
    52  * int param_3 = obj.getRandom();
    53  */
    My Code

    RE一万年,发现是忽略了“remove时如果m[val]已经被删空,应该erase掉”这种情况

    还是挺有趣的一道题目。

    ====================================================================

    532讲的是
    输入n个数字a[i](无序,-1e7<=a[i]<=1e7,n<=1e4)和一个数字k,问你其中有多少不同的数对。
    数对的定义:(i,j)是数对当且仅当abs(i-j)==k

    我的思路
    暴力的话就是排序去重,然后一个个压到hash中判断加减k是否有数据。O(nlogn)
    后来想了想,感觉O{n}也可以,永远用后进入的数字来匹配之前的,就可以保证不重复。(如果有重复的数字要进入,就跳过)。
    然后发现k居然可以等于0,丧心病狂,分开处理好了。。。

     1 class Solution {
     2 public:
     3     int findPairs(vector<int>& nums, int k) {
     4         int ans=0;
     5         int n=nums.size();
     6         if(n<2)return 0;
     7         unordered_map<int,int> m;
     8         if(k){
     9             if(k<0)return 0;
    10             for(int i=0;i<n;i++){
    11                 int temp=nums[i],aim;
    12                 if(m.find(temp)!=m.end())continue;
    13                 aim=temp+k;
    14                 if(m.find(aim)!=m.end())ans++;
    15                 aim=temp-k;
    16                 if(m.find(aim)!=m.end())ans++;
    17                 m[temp]=1;
    18             }
    19         }else{
    20             for(int i=0;i<n;i++){
    21                 int temp=nums[i];
    22                 if(m.find(temp)!=m.end()){
    23                     if(m[temp]==1){
    24                         ans++;
    25                         m[temp]++;
    26                     }
    27                 }else{
    28                     m[temp]=1;
    29                 }
    30             }
    31         }
    32         return ans;
    33     }
    34 };
    532

     又是一道可以用python一行解决的题目(害怕)

    1 def findPairs(self, nums, k):
    2        return len(set(nums)&{n+k for n in nums}) if k>0 else sum(v>1 for v in collections.Counter(nums).values()) if k==0 else 0

    展开是这样的

    1 def findPairs(self, nums, k):
    2         if k>0:
    3             return len(set(nums)&set(n+k for n in nums))
    4         elif k==0:
    5             return sum(v>1 for v in collections.Counter(nums).values())
    6         else:
    7             return 0
  • 相关阅读:
    H5页面获取屏幕宽高
    装修注意事项
    两列等高布局
    html/css
    css的几种垂直水平居中方法
    3分钟看懂flex布局
    Android手机里H5页面滚动图片时出现白屏
    JavaScript正则表达式——函数
    javascript正则表达式——语法
    【react】子组件向父组件传值
  • 原文地址:https://www.cnblogs.com/xuwangzihao/p/6519795.html
Copyright © 2020-2023  润新知