前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >gcd,哈希问题-LeetCode 357、355、365、367、380

gcd,哈希问题-LeetCode 357、355、365、367、380

作者头像
算法工程师之路
发布2019-12-01 13:58:44
5160
发布2019-12-01 13:58:44
举报
文章被收录于专栏:算法工程师之路

gcd,哈希表问题:LeetCode #357 355 365 367 380

1

编程题

【LeetCode #357】计算各个位数不同的数字个数

给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n 。

示例: 输入: 2 输出: 91 解释: 答案应为除去 11,22,33,44,55,66,77,88,99 外,在 [0,100) 区间内的所有数字。

解题思路:

n = 1时,res = 10; n = 2时,两位数符合条件的有99,首位不能是零!然后再加上n=1时的结果 n = 3时,三位数符合条件的有99*8, 然后再加上n=2时的结果! 注意:n>10时,必定重复,结果为零!

代码语言:javascript
复制
class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        int res = 0;
        if(n == 0) return 1;
        if(n > 10) return 0;
        res = 10;
        int tmp = 9;   // 多位数的第一位不为零,因此有9种选择
        for(int i = 1; i < n; i++){
            tmp *= (10-i);
            res += tmp;   // 加上前一位数的个数
        }
        return res;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/count-numbers-with-unique-digits

【LeetCode #355】设计推特

设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近十条推文。你的设计需要支持以下的几个功能:

postTweet(userId, tweetId): 创建一条新的推文 getNewsFeed(userId): 检索最近的十条推文。每个推文都必须是由此用户关注的人或者是用户自己发出的。推文必须按照时间顺序由最近的开始排序。 follow(followerId, followeeId): 关注一个用户 unfollow(followerId, followeeId): 取消关注一个用户

示例: Twitter twitter = new Twitter(); // 用户1发送了一条新推文 (用户id = 1, 推文id = 5). twitter.postTweet(1, 5); // 用户1的获取推文应当返回一个列表,其中包含一个id为5的推文. twitter.getNewsFeed(1); // 用户1关注了用户2. twitter.follow(1, 2); // 用户2发送了一个新推文 (推文id = 6). twitter.postTweet(2, 6); // 用户1的获取推文应当返回一个列表,其中包含两个推文,id分别为 -> [6, 5]. // 推文id6应当在推文id5之前,因为它是在5之后发送的. twitter.getNewsFeed(1); // 用户1取消关注了用户2. twitter.unfollow(1, 2); // 用户1的获取推文应当返回一个列表,其中包含一个id为5的推文. // 因为用户1已经不再关注用户2. twitter.getNewsFeed(1);

解题思路:

首先设计两个map,一个用于储存用户之间的关系follows,即某用户订阅了那些用户,另一个用于保存某用户发了那些推特,由于题目中需要按照发表时间排序,因此tweets的数据类型为map<int, vector<pair>>, 由于一个人会发多篇,使用vector储存,每个tweet都有对应时间,因此使用pair.,>,="">

主要在于getNewsFeed函数,当获取tweet时,我们应该将自己以及该用户订阅的所有人的推文放到一起,按照时间排序,取出时间最大的前10个推文即可! 有可能总推文数没有10个,因此使用int n = min(10, (int)tmp.size());来获取个数!

代码语言:javascript
复制
class Twitter {
public:
    map<int, vector<pair<int, long long>>> tweets;
    map<int, set<int>> follows;
    long long times = 0;
    /** Initialize your data structure here. */
    Twitter() {
    }

    /** Compose a new tweet. */
    void postTweet(int userId, int tweetId) {
        tweets[userId].emplace_back(tweetId, times++);
    }

    /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */
    vector<int> getNewsFeed(int userId) {     
        vector<int> res;
        vector<pair<int, long long>> tmp;
        follows[userId].insert(userId);
        for(auto usr: follows[userId]){     // 该用户订阅了那些人
            for(auto tw: tweets[usr]){
                tmp.push_back(tw);
            }
        }
        sort(tmp.begin(), tmp.end(), [](pair<int, long long>a, pair<int, long long>b){
            return a.second > b.second;
        });
        int n = min(10, (int)tmp.size());
        for(int i = 0; i < n; i++){
            res.push_back(tmp[i].first);
        }
        return res;
    }

    /** Follower follows a followee. If the operation is invalid, it should be a no-op. */
    void follow(int followerId, int followeeId) {
        follows[followerId].insert(followeeId);     // key为订阅者,value为被订阅者
    }

    /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
    void unfollow(int followerId, int followeeId) {
        follows[followerId].erase(followeeId);
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/design-twitter

【LeetCode #365】水壶问题

有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。 你允许:

  • 装满任意一个水壶
  • 清空任意一个水壶
  • 从一个水壶向另外一个水壶倒水,直到装满或者倒空

示例 1: (From the famous "Die Hard" example) 输入: x = 3, y = 5, z = 4 输出: True

解题思路:

这个是数学问题,即寻找x和y的最大公约数,然后z为其最大公约数的整数倍。 最大公约数算法也叫gcd,至于算法原理来自一个数学定理,记下好了!剩余的就是一些边界条件问题!

代码语言:javascript
复制
class Solution {
public:
    int gcd(int x, int y){
        if(y == 0) return x;
        int r = x % y;
        return gcd(y, r);
    }
    bool canMeasureWater(int x, int y, int z) {
        if(x == 0 && y == 0) return z == 0;
        return z == 0 || (z % gcd(x, y) == 0 && (x+y) >= z);
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/water-and-jug-problem

【LeetCode #367】有效的完全平方数

给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。 说明:不要使用任何内置的库函数,如 sqrt。

示例 1: 输入:16 输出:True

解题思路:

使用二分查找,但需要注意的是INT的最大值为2147483647,因此平方的底数最大为46340,设置这个上限即可!

代码语言:javascript
复制
class Solution {
public:
    bool isPerfectSquare(int num) {
        int l = 0, r = 46340;
        while(l <= r){ 
            int mid = l + (r - l) / 2;
            long power = mid * mid;
            if(power > num){
                r = mid -1;
            }
            else if(power < num){
                l = mid +1;
            }
            else{
                return true;
            }
        }
        return false;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/valid-perfect-square

【LeetCode #380】常数时间插入、删除和获取随机元素

设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。

insert(val):当元素 val 不存在时,向集合中插入该项。 remove(val):元素 val 存在时,从集合中移除该项。 getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。

代码语言:javascript
复制
class RandomizedSet {
public:
    /** Initialize your data structure here. */
    unordered_set<int> s;
    RandomizedSet() {}

    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    bool insert(int val) {
        if(s.count(val)) return false;
        s.insert(val);
        return true;
    }

    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        if(s.count(val) == 0) return false;
        s.erase(val);
        return true;
    }

    /** Get a random element from the set. */
    int getRandom() {
        auto it = s.begin();
        int step = rand() % s.size();
        while(step--){
            //it++;
            it = next(it);
        }
        return *it;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/insert-delete-getrandom-o1

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法工程师之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档