不给自己任何借口
今日题目:
1、插入删除获得随机 O(1); tag:数组|哈希表|设计
2、猜数字大小 II tag:DP
今日摘录:
把世上全部的酒都喝干,让你和所有人都清醒着与我交谈,告诉我那些不中听的话,伴我入眠。
380. Insert Delete GetRandom O(1) | Difficulty: Medium
Design a data structure that supports all following operations in average O(1) time.
insert(val): Inserts an item val to the set if not already present.
remove(val): Removes an item val from the set if present.
getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.
tag:数组|哈希表|设计
题意:设计一个数据结构,满足插入删除获得随机元素均为O(1)复杂度。
思路:
1、首先建立一个unordered_map,对于这个集合,还建立一个相应的数组用来保存集合中现有的元素。
插入需要判断元素是否在集合中,如果已经在了就返回false,如果不在集合中,向集合中插入元素,key为当前待插入元素,value为该元素目前在数组中的位置,并且相应数组也要加入元素。
删除元素如果不存在返回false,如果存在会有一个问题就是当前元素不一定在末尾,那么相应的数组就做不到弹出末尾元素,这个时候怎么做呢?一个很直观的思路就是交换当前待删除元素和最末尾元素,只用将最末尾元素相对应的value改成待删除元素相对应的value并且讲数组中的被删除元素改成末尾元素,最后弹出末尾元素即可。
最后返回随机元素比较简单。
class RandomizedSet {
public:
/** Initialize your data structure here. */
RandomizedSet() {
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val) {
//首先判断是否集合中包含该元素
if(map.find(val)!=map.end()) return false;
nums.emplace_back(val);
map[val] = nums.size()-1;
return true;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val) {
if(map.find(val)==map.end()) return false;
int last = nums.back();
map[last] = map[val];
nums[map[val]] = last;
nums.pop_back();
map.erase(val);
return true;
}
/** Get a random element from the set. */
int getRandom() {
return nums[rand() % nums.size()];
}
private:
vector<int> nums;
unordered_map<int,int> map;
};
/**
* Your RandomizedSet object will be instantiated and called as such:
* RandomizedSet obj = new RandomizedSet();
* bool param_1 = obj.insert(val);
* bool param_2 = obj.remove(val);
* int param_3 = obj.getRandom();
*/
结果:72ms
375. Guess Number Higher or Lower II | Difficulty: Medium
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I’ll tell you whether the number I picked is higher or lower.
However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
Example:
n = 10, I pick 8.
First round: You guess 5, I tell you that it’s higher. You pay
5.Secondround:Youguess7,Itellyouthatit′shigher.Youpay
7.
Third round: You guess 9, I tell you that it’s lower. You pay $9.
Game over. 8 is the number I picked.
You end up paying
5+
7 +
9=
21.
Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.
tag:DP
题意:猜大小,找到保证能赢的最少钱数
思路:
1、针对每一种可能取值情况,去计算该取值下剩下的钱数,比如首先猜i元,那么此时花的钱就是i+max(继续从start到i-1去猜,继续从i+1到end去猜),对于此时所有能猜的i,找到其中最小的可能钱数。
class Solution {
public:
int getMoneyAmount(int n) {
vector<vector<int> > grid(n+1,vector<int>(n+1,0));
return DP(grid,1,n);
}
int DP(vector<vector<int>>&grid,int start,int end)
{
if(start>=end) return 0;
if(grid[start][end]!=0) return grid[start][end];
int res = INT_MAX;
for(int i=start;i<=end;i++)
{
int tmp = i+max(DP(grid,i+1,end),DP(grid,start,i-1));
res =min(res,tmp);
}
grid[start][end] = res;
return res;
}
};
结果:80ms