石器时代 —— Leetcode刷题(ByteDance)

440. 字典序的第K小数字

原题

  • 建模(10叉树的前序遍历)
    在这里插入图片描述
  • 0 1 10 11 12 13 2 3 4 5 6 7 8 9 (从1开始,去掉0)
  • 流程:
    • 其实只需要按层节点个数计算即可,图中节点1和节点2在第二层,因为n = 13,节点1可以移动到节点2(同一层)所以在第二层需要移动1步。
    • 第三层,移动个数就是 (13 - 10 + 1) = 4 (min(13 + 1, 20) - 10)所以节点1到节点2需要移动 1 + 4 = 5 步
    • 当移动步数小于等于k,说明需要向右节点移动,图中就是节点1移动到节点2
    • 当移动步数大于k,说明目标值在节点1和节点2之间,我们要向下移动!即从节点1移动到节点10。
class Solution {
public:
    int cal_steps(long int n, long int n1, long int n2) {
        int step = 0;
        while (n1 <= n) {
            step += min(n2, n + 1) - n1;
            n1 *= 10;
            n2 *= 10;
        }
        return step;
    }
    int findKthNumber(int n, int k) {
        int cur = 1;
        k -= 1;
        while (k > 0) {
            int steps = cal_steps(n, cur, cur + 1);
            if (steps <= k) {
                k -= steps;
                cur += 1;
            } else {
                k -= 1;
                cur *= 10;
            }
        }
        return cur;
    }
};

726. 原子的数量

原题

DFS

  • 判断条件 ()其他
class Solution {
public:
    string countOfAtoms(string formula) {
        int pos = 0;
        string res = "";
        map<string, int> m = parse(formula, pos);
        for (auto& x : m) {
            res += x.first + (x.second == 1 ? "" : to_string(x.second));
        }
        return res;
    }
    map<string, int> parse(string& x, int& pos) {
        map<string, int> m;
        while (pos < x.size()) {
            if (x[pos] == '(') {
                pos++;
                for (auto& a : parse(x, pos)) 
                    m[a.first] += a.second;
            } else if (x[pos] == ')') {
                int i = ++pos;
                while (pos < x.size() && isdigit(x[pos])) ++pos;
                int multi = stoi(x.substr(i, pos - i)); // 乘数
                for (auto& a : m) m[a.first] *= multi;
                return m;
            } else {
                int i = pos++;
                while (pos < x.size() && islower(x[pos])) ++pos;
                string elem = x.substr(i, pos - i); i = pos; // 元素名字
                while (pos < x.size() && isdigit(x[pos])) ++pos;
                string cnt = x.substr(i, pos - i);
                m[elem] += cnt.empty() ? 1 : stoi(cnt); // 加数
            }
        }
        return m;
    }
};

Stack

  • 使用栈来代替递归函数,本身之上基本没有任何区别
  • std::move(t):用来表明对象t是可以moved from的,它允许高效的从t资源转换到lvalue上
class Solution {
public:
    string countOfAtoms(string formula) {
        string res = "";
        int pos = 0;
        map<string, int> cur;
        stack<map<string, int>> st;
        int N = formula.size();
        while (pos < N) {
            if (formula[pos] == '(') {
                pos++;
                st.push(move(cur)); // 现场保护起来 m移到st m清空
            } else if (formula[pos] == ')') {
                int i = ++pos;
                while (pos < N && isdigit(formula[pos])) ++pos;
                int multi = stoi(formula.substr(i, pos - i));
                for (auto& a : cur) st.top()[a.first] += a.second * multi;
                cur = move(st.top());
                st.pop();
            } else {
                int i = pos++;
                while (pos < N && islower(formula[pos])) ++pos;
                string elem = formula.substr(i, pos - i);
                i = pos;
                while (pos < N && isdigit(formula[pos])) ++pos;
                string cnt = formula.substr(i, pos - i);
                cur[elem] += cnt.empty() ? 1 : stoi(cnt);
            }
        }
        for (auto& a : cur) {
            res += a.first + (a.second == 1 ? "" : to_string(a.second));
        }
        return res;
    }
};

1188. 设计有限阻塞队列

参考

  • 信号量sem
  • pthread库

199. 二叉树的右视图

参考

BFS

  • 单向队列!按层存!
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        if (!root) return {};
        queue<TreeNode*> q;
        q.push(root);
        vector<int> res;
        while (!q.empty()) {
            res.push_back(q.front()->val);
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                auto x = q.front(); q.pop();
                if (x->right) q.push(x->right);
                if (x->left) q.push(x->left);
            }
        }
        return res;
    }
};

DFS

  • 先往右搜索,当深度第一达到,就存下!
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        int depth = 0;
        vector<int> res;
        dfs(root, res, depth);
        return res;
    }
    void dfs(TreeNode* root, vector<int>& res, int dep) {
        if (!root) return;
        if (res.size() == dep) res.push_back(root->val);
        dfs(root->right, res, dep+1);
        dfs(root->left, res, dep+1);
    }
};

135. 分发糖果

参考

  • 贪心
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值