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=;
  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-){
  28. v[a[n-]]=ptr;
  29. a[ptr]=a[n-];
  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() - ));
  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()-));
  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 -;
  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=;
  5. int n=nums.size();
  6. if(n<)return ;
  7. unordered_map<int,int> m;
  8. if(k){
  9. if(k<)return ;
  10. for(int i=;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]=;
  18. }
  19. }else{
  20. for(int i=;i<n;i++){
  21. int temp=nums[i];
  22. if(m.find(temp)!=m.end()){
  23. if(m[temp]==){
  24. ans++;
  25. m[temp]++;
  26. }
  27. }else{
  28. m[temp]=;
  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

2017-3-8 leetcode 380 381 532的更多相关文章

  1. 2017/11/22 Leetcode 日记

    2017/11/22 Leetcode 日记 136. Single Number Given an array of integers, every element appears twice ex ...

  2. 2017/11/21 Leetcode 日记

    2017/11/21 Leetcode 日记 496. Next Greater Element I You are given two arrays (without duplicates) num ...

  3. 2017/11/13 Leetcode 日记

    2017/11/13 Leetcode 日记 463. Island Perimeter You are given a map in form of a two-dimensional intege ...

  4. 2017/11/20 Leetcode 日记

    2017/11/14 Leetcode 日记 442. Find All Duplicates in an Array Given an array of integers, 1 ≤ a[i] ≤ n ...

  5. 2017/11/9 Leetcode 日记

    2017/11/9 Leetcode 日记 566. Reshape the Matrix In MATLAB, there is a very useful function called 'res ...

  6. 2017/11/7 Leetcode 日记

    2017/11/7 Leetcode 日记 669. Trim a Binary Search Tree Given a binary search tree and the lowest and h ...

  7. 2017/11/6 Leetcode 日记

    2017/11/6 Leetcode 日记 344. Reverse String Write a function that takes a string as input and returns ...

  8. 2017/11/5 Leetcode 日记

    2017/11/5 Leetcode 日记 476. Number Complement Given a positive integer, output its complement number. ...

  9. 2017/11/3 Leetcode 日记

    2017/11/3 Leetcode 日记 654. Maximum Binary Tree Given an integer array with no duplicates. A maximum ...

随机推荐

  1. MySQL定期执行任务相关问题

    在sqlyog某数据库下的事件里新建事件,并写入一下代码: DELIMITER $$ ALTER DEFINER=`root`@`%` EVENT `0` ON SCHEDULE EVERY 24 H ...

  2. PHP获取远程和本地文件信息(汇总)

    1.PHP filesize() 函数filesize() 函数返回指定文件的大小.若成功,则返回文件大小的字节数.若失败,则返回 false 并生成一条 E_WARNING 级的错误. 但是只能获取 ...

  3. ThinkPHP3.2.3对数据的添、删、改、查(CURD)

    对数据的添加: public function form() { parent::common(); $obj = D('Leave'); if (IS_POST) { $data = I('post ...

  4. 金立 M6 (GN8003) 解锁 BootLoader 进入第三方 recovery 刷机 ROOT

    首先下载好工具:http://url.cn/5EILbQn 备用连接 :http://pan.baidu.com/s/1c28j7k0 本篇教程教你如何傻瓜式解锁BootLoader并刷入recove ...

  5. 《深入理解Android虚拟机内存管理》示例程序编译阶段生成的各种语法树完整版

    1.tokens "int"                   "int" <SPACES>                " &quo ...

  6. linux 新添加的硬盘格式化并挂载到目录下

    需求: 新增加一块硬盘sdb,将sdb分区,只分一个区,格式化,挂载到目录/ssd下. 1.  查看现在已有的分区状态 # df –l 图中显示,没有看到sdb硬盘 2.  查看服务器安装的硬盘状态( ...

  7. oracle 命令记录

    监听程序启动停止查看名利: 1.切换到oracle用户:su - oracle 2.查看监听状态:lsnrctl status 3.停止监听:lsnrctl stop 4.启动监听:lsnrctl s ...

  8. EnforceLearning-主动强化学习

    前言: 被动学习Agent由固定的策略决定其行为.主动学习Agent必须自己决定采取什么行动. 具体方法是: Agent将要学习一个包含所有行动结果概率的完整模型,而不仅仅是固定策略的模型: 接下来, ...

  9. Vue select默认选中第一个

    <td> <select v-model="selectWare"> <option selected="selected" va ...

  10. 51nod1081 子段求和

    给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和. 例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1.3 + 7 + 9 = ...