力扣模拟题刷题

目录

[1404. 将二进制表示减到 1 的步骤数](#1404. 将二进制表示减到 1 的步骤数)

[2460. 对数组执行操作](#2460. 对数组执行操作)

[2365. 任务调度器 II](#2365. 任务调度器 II)

[2109. 向字符串添加空格](#2109. 向字符串添加空格)

[LCR 002. 二进制求和](#LCR 002. 二进制求和)

[3688. 偶数的按位或运算](#3688. 偶数的按位或运算)

[2073. 买票需要的时间](#2073. 买票需要的时间)

[3834. 合并相邻且相等的元素](#3834. 合并相邻且相等的元素)

[2079. 给植物浇水](#2079. 给植物浇水)


1404. 将二进制表示减到 1 的步骤数

法一:用carry存储进位值(感觉跟高精度运算原理差不多)

cpp 复制代码
class Solution {
public:
    int numSteps(string s) {
        int ans=s.size()-1;
        int carry=0;
        for(int i=s.size()-1;i>0;i--){
            int sum=s[i]-'0'+carry;
            ans+=sum%2;
            carry=(sum+sum%2)/2;
        }
        return ans+carry;
    }
};

注释详解版本:

cpp 复制代码
class Solution {
public:
    int numSteps(string s) {
        //初始化:除了最高位不需要操作,其他位至少操作1次
        int ans=s.size()-1;
        //进位
        int carry=0;
        for(int i=s.size()-1;i>0;i--){
            int sum=s[i]-'0'+carry;
            //sum可以是0/1/2
            //为什么要%2?
            //sum是偶数时,不需要额外操作,ans+=0
            //sum是奇数时,需要额外进位,ans+=1
            ans+=sum%2;
            //sum是0时,carry=0,不需要进位
            //sum是1时,要先+1,这一位变成了2,所以要进1
            //sum是2时,说明原位是1,进位是1,还要向更高位进位
            //也可以写成:carry = (sum >= 1 ? 1 : 0);
            carry=(sum+sum%2)/2;
        }
        //for中没有处理最高位,如果有进位的话,还需一次操作
        return ans+carry;
    }
};

当然,可以写成更易懂的代码:

cpp 复制代码
class Solution {
public:
    int numSteps(string s) {
        int n=s.size();
        int ans=n-1;
        int carry=0;
        for(int i=n-1;i>0;i--){
            int bit=s[i]-'0';
            int cur=bit+carry;
            if(cur==1){
                ans++;
            }
            if(cur>=1){
                //必然产生进位,如果是1就要先+1,如果是2就要向更高位进位
                carry=1;
            }
            else if(cur==0){
                carry=0;
            }
        }
        return ans+carry;
    }
};

法二:暴力模拟,时O(N)

cpp 复制代码
class Solution {
public:
    int numSteps(string s) {
        int ans = 0;
        while (s != "1") {
            ans++;
            if (s.back() == '0') {
                s.pop_back();
            } else {
                for (int i = s.size() - 1; i >= 0; i--) {
                    if (s[i] == '1') {
                        s[i] = '0';
                        if (i == 0) {
                            s = "1" + s;
                            break;
                        }
                    } else {
                        s[i] = '1';
                        break;
                    }
                }
            }
        }
        return ans;
    }
};

2460. 对数组执行操作

cpp 复制代码
class Solution {
public:
    vector<int> applyOperations(vector<int>& nums) {
        vector<int> ans;
        for (int i = 0; i < nums.size() - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                nums[i] *= 2;
                nums[i + 1] = 0;
            }
            if(nums[i])ans.push_back(nums[i]);
        }
        ans.push_back(nums[nums.size() - 1]);
        ans.resize(nums.size());
        return ans;
    }
};

2365. 任务调度器 II

暴力解法(超时):模拟冷却倒计时

缺点是每次都要维护所有状态

cpp 复制代码
class Solution {
public:
    long long taskSchedulerII(vector<int>& tasks, int space) {
        long long ans=0;
        unordered_map<int,int>map;
        for(int t:tasks){
            int days=map[t]+1;
            ans+=days;
            for(auto& [key,val]:map){
                val=max(0,val-days);
            }
            map[t]=space;
        }
        return ans;
    }
};

优化:只要记录对于某个任务t,下次最早可以执行是什么时候

cpp 复制代码
class Solution {
public:
    long long taskSchedulerII(vector<int>& tasks, int space) {
        //day指当前日期
        long long day=0;
        //nextDay指该任务下一次可以执行的日期
        unordered_map<int,long long>nextDay;
        for(int t:tasks){
            //若无限制,下一天(day+1)就可以执行
            //若有限制,在nextDay[t]时才可以执行
            day=max(day+1,nextDay[t]);
            //该任务下一次可以执行的日期是day+space+1
            nextDay[t]=day+space+1;
        }
        return day;
    }
};

2109. 向字符串添加空格

直接模拟题意即可

主要掌握substr用法

cpp 复制代码
class Solution {
public:
    string addSpaces(string s, vector<int>& spaces) {
        string ans=s.substr(0,spaces[0]);
        for(int i=1;i<spaces.size();i++){
            ans+=" ";
            ans+=s.substr(spaces[i-1],spaces[i]-spaces[i-1]);
        }
        if(spaces[spaces.size()-1]!=s.size()){
            ans+=" ";
            ans+=s.substr(spaces[spaces.size()-1],s.size()-spaces[spaces.size()-1]);
        }
        return ans;
    }
};

LCR 002. 二进制求和

按照题意暴力模拟

和高精度差不多,又是carry记录进位

cpp 复制代码
class Solution {
public:
    string addBinary(string a, string b) {
        string ans = "";
        reverse(a.begin(),a.end());
        reverse(b.begin(),b.end());
        int carry = 0;
        int p = 0;
        while (p < min(a.size(), b.size())) {
            int cur = (a[p]-'0' )+ (b[p]-'0') + carry;
            ans += to_string(cur % 2);
            carry = cur / 2;
            p++;
        }
        while (p < a.size()) {
            int cur = (a[p]-'0') + carry;
            ans += to_string(cur % 2);
            carry = cur / 2;
            p++;
        }
        while (p < b.size()) {
            int cur = (b[p]-'0') + carry;
            ans += to_string(cur % 2);
            carry = cur / 2;
            p++;
        }
        if(carry)ans+=to_string(carry);
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

或者p可以取高位,这样就不用反转a和b了

3688. 偶数的按位或运算

简单,不过要知道按位或的符号是|

cpp 复制代码
class Solution {
public:
    int evenNumberBitwiseORs(vector<int>& nums) {
        int ans=0;
        for(int i:nums){
            if(i%2==0)ans=ans|i;
        }
        return ans;
    }
};

2073. 买票需要的时间

队列模拟(注意下标不是i+1==k)

cpp 复制代码
class Solution {
public:
    int timeRequiredToBuy(vector<int>& tickets, int k) {
        queue<pair<int,int>>q;
        for(int i=0;i<tickets.size();i++){
            if(i==k)q.push({tickets[i],1});
            else q.push({tickets[i],0});
        }
        int ans=0;
        while(!q.empty()){
            auto t=q.front();
            q.pop();
            ans++;
            t.first--;
            if(t.second==1&&t.first==0)break;
            if(t.first>0)q.push({t.first,t.second});
        }
        return ans;
    }
};

3834. 合并相邻且相等的元素

用栈模拟(栈不一定要用stack,用vector也行)

先进后出

cpp 复制代码
class Solution {
public:
    vector<long long> mergeAdjacent(vector<int>& nums) {
        vector<long long>ans;
        for(int i:nums){
            ans.push_back(i);
            while(ans.size()>1&&ans[ans.size()-1]==ans[ans.size()-2]){
                ans.pop_back();
                ans[ans.size()-1]*=2;
            }
        }
        return ans;
    }
};

先出后进(注意i要设置为long long)

cpp 复制代码
class Solution {
public:
    vector<long long> mergeAdjacent(vector<int>& nums) {
        vector<long long>ans;
        for(long long i:nums){
            while(!ans.empty()&&ans.back()==i){
                ans.pop_back();
                i*=2;
            }
            ans.push_back(i);
        }
        return ans;
    }
};

2079. 给植物浇水

直接按照题意模拟

注意仔细讨论每种情况

cpp 复制代码
class Solution {
public:
    int wateringPlants(vector<int>& plants, int capacity) {
        int ans = 0;
        int cur = capacity;
        int p = -1;
        for (int i = 0; i < plants.size(); i++) {
            if (p == -1) {
                ans += i - p;
                cur = capacity - plants[i];
                p = i;
            } else {
                if (cur < plants[i]) {
                    ans += p + 1;
                    ans += i + 1;
                    p = i;
                    cur = capacity - plants[i];
                } else {
                    ans += i - p;
                    cur -= plants[i];
                    p = i;
                }
            }
        }
        return ans;
    }
};

优化:不用维护p,因为每次都是向右走

cpp 复制代码
class Solution {
public:
    int wateringPlants(vector<int>& plants, int capacity) {
        int ans = 0;
        int cur = capacity;
        for (int i = 0; i < plants.size(); i++) {
            if (cur < plants[i]) {
                ans += i * 2;
                cur = capacity;
            }
            cur -= plants[i];
            ans++;
        }
        return ans;
    }
};
相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法