zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Parameter Binding in ASP.NET Web API
    Which HTTP methods match up to which CRUD methods?
    ErrorHandling in asp.net web api
    HttpStatusCode
    Autofac Getting Started(默认的构造函数注入)
    Autofac Controlling Scope and Lifetime
    luvit 被忽视的lua 高性能框架(仿nodejs)
    undefined与null的区别
    VsCode中使用Emmet神器快速编写HTML代码
    字符串匹配---KMP算法
  • 原文地址:https://www.cnblogs.com/xuwangzihao/p/6519795.html
Copyright © 2011-2022 走看看