leetcode题解日练--2016.8.5

不给自己任何借口

今日题目:

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,Itellyouthatitshigher.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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值