leecode每日一练

打家劫舍

在这里插入图片描述

我一开始的思路也是dp,但是转移方程想错了,这个题目转移方程应该是dp[i] = max(dp[i-2]+nums[i],dp[i-1])

class Solution {
public:
    int rob(vector<int>& nums) {
        int len = nums.size();
        vector<int> dp(len);
        int ans = 0;
        if(len>=1)
        dp[0] = nums[0],ans=max(ans,dp[0]);
        if(len>=2)
        dp[1] = max(nums[0],nums[1]),ans=max(ans,dp[1]);
        for(int i=2;i<len;i++){
            dp[i] = max(dp[i-2]+nums[i],dp[i-1]);
            ans = max(ans,dp[i]);
        }
        return ans;
    }
};

拆炸弹

在这里插入图片描述
纯模拟就是sb,我用了差分数组,但是转移方程写死我了
我写的代码

class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        int len = code.size();
        vector<int> ans(len);
        vector<int> p(len+1);
        p[0] = code[0];
        for(int i=1;i<len;i++){
            p[i] = p[i-1]+code[i];
        }
        if(k==0){
            return ans;
        }
        else if(k>0){
            for(int i=0;i<len;i++){
                if(i+k<len){
                    ans[i] += p[i+k]-p[i];
                }else{
                    ans[i] += p[len-1]-p[i];
                    int cha = k-(len-1-i);
                    if(cha>0)
                    ans[i] += p[cha-1];
                }
            }
            
        }else{
            k = -k;
            for(int i=0;i<len;i++){
                if(i>k){
                    if(i-1-k>=0)
                    ans[i] += p[i-1]-p[i-1-k];
                    else{
                        ans[i] += p[i-1];
                    }
                }else{
                    if(i>0)
                    ans[i] += p[i-1];
                    int cha = k-i;
                    ans[i] += p[len-1]-p[len-1-cha];
                }
            }
        }
        return ans;
    }
};

但是其实只要开两倍的空间就可以简单完成,下面这个思路是滑动窗口,但是其实差分也是可以的

class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        int n = code.size();
        vector<int> res(n);
        if (k == 0) {
            return res;
        }
        code.resize(n * 2);
        copy(code.begin(), code.begin() + n, code.begin() + n);
        int l = k > 0 ? 1 : n + k;
        int r = k > 0 ? k : n - 1;
        int w = 0;
        for (int i = l; i <= r; i++) {
            w += code[i];
        }
        for (int i = 0; i < n; i++) {
            res[i] = w;
            w -= code[l];
            w += code[r + 1];
            l++;
            r++;
        }
        return res;
    }
};

基站建设

题目地址
在这里插入图片描述

一开始我的思路是差分,但是只能过五分之一的数据集,这是因为如果这些重叠的区域过多的话就会出现问题

给你看一下差分的代码

#include<bits/stdc++.h>
using namespace std;

const int N = 1000005;
int s[N];
int p[N];
int n;


int main() {
	cin >> n;
	int a, b;
	int mm = 0;
	for (int i = 1; i <= n; i++) {
		cin >> a >> b;
		int l = (a - b) > 1 ? a - b : 1;
		int r = (a + b) < N ? a + b : N - 1; mm = max(mm, r);
		s[l] += 1;
		s[r + 1] -= 1;
	}
	for (int i = 1; i <= mm; i++) {
		p[i] += p[i - 1] + s[i];
	}
	int re = 0;
	int now;
	int flag = 0;
	for (int i = 1; i <= mm; i++) {
		//cout << p[i] << " ";
		if (flag == 0 && p[i] > 1) {
			flag = 1; // 进入区域
			now = p[i];
		}
		if (flag == 1 && p[i] <= 1) {
			flag = 0; //出去
			re += now - 1;
		}
		if (flag == 1 && p[i] > 1) {
			now = max(now, p[i]);
		}
	}
	cout << n - re;
	return 0;
}

应该用贪心来做,就是一个活动安排问题

#include<bits/stdc++.h>
using namespace std;

const int N = 1000005;
struct node
{
	int start, end;
	bool operator<(node b) {
		return this->end < b.end;
	}
}a[N];

int n;
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int x, b;
		cin >> x >> b;
		a[i].start = x - b;
		a[i].end = x + b;
	}
	sort(a + 1, a + 1 + n);
	if (n == 0) {
		cout << 0;
		return 0;
	}
	int ans = 1;
	int now = a[1].end;
	for (int i = 2; i <= n; i++) {
		if (a[i].start <= now) continue;
		now = a[i].end; ans++;
	}
	cout << ans;
	return 0;
}

leecode 每日温度

在这里插入图片描述

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        int len = temperatures.size();
        deque<int> p;
        vector<int> ans(len);
        for (int i = 0; i < len; i++) {
            int temp = temperatures[i];
            while (p.size() && temp > temperatures[p.back()]) {
                int po = p.back();
                cout << "尾巴的 " << po << endl;
                p.pop_back();
                ans[po] = i - po;
            }
            p.push_back(i);
        }
        return ans;
    }
};

leecode 1475

在这里插入图片描述

class Solution {
public:
    vector<int> finalPrices(vector<int>& prices) {
        int len = prices.size();
        vector<int> ans(len);
        deque<int> q;
        for (int i = 0; i < len; i++) {
            int now = prices[i];
            while (q.size()&&now<=prices[q.back()])
            {
                int pos = q.back();
                q.pop_back();
                ans[pos] = prices[pos] - now;
            }
            q.push_back(i);
        }
        // 别忘记这一步
        while(q.size()){
            int pos = q.back();
            ans[pos] = prices[pos];
            q.pop_back();
        }
        return ans;
    }
};

落谷2422

在这里插入图片描述
我们还要注意退出for循环后的边界处理,这时候单调栈里面还有东西

#include<bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1e5 + 5;
int a[N];
int n;
int ans = 0;
int p[N];
int l[N], r[N];


signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		p[i] = p[i - 1] + a[i];
		l[i] = r[i] = i;
	}
	deque<int> q;
	for (int i = 1; i <= n; i++) {
		int now = a[i];
		while (q.size()&& now<a[q.back()])
		{
			int  u = q.back();
			q.pop_back();
			r[u] = i;
		}
		q.push_back(i);
	}
	while (q.size()) {
		int u = q.back();
		q.pop_back();
		r[u] = n+1;
	}
	q.clear();
	for (int i = n; i >= 1; i--) {
		int now = a[i];
		while (q.size() && now < a[q.back()]) {
			int  u = q.back();
			q.pop_back();
			l[u] = i;
		}
		q.push_back(i);
	}
	while (q.size())
	{
		int u = q.back();
		q.pop_back();
		l[u] = 0;
	}
	for (int i = 1; i <= n; i++) {
		ans = max(ans, a[i] * (p[r[i]-1] - p[l[i]]));
	}
	//for (int i = 1; i <= n; i++) {
	//	cout << l[i] << " " << r[i] << endl;

	//}
	cout << ans;

	return 0;
}

leecode2244

在这里插入图片描述

class Solution {
public:
    int minimumRounds(vector<int>& tasks) {
        unordered_map<int, int> cnt;
        for (int t : tasks) {
            cnt[t]++;
        }
        int ans = 0;
        for (auto& [_, c] : cnt) {
            if (c == 1) {
                return -1;
            }
            ans += (c + 2) / 3;
        }
        return ans;
    }
};

leecode2589

在这里插入图片描述
这个题目和活动安排问题很相似,所以采用贪心的思路
我的代码

class Solution {
public:
    int findMinimumTime(vector<vector<int>>& tasks) {
        vector<int> d(20005,0);
        sort(tasks.begin(), tasks.end(), cmp);
        int len = tasks.size();
        int ans = 0;
        for (int i = 0; i < len; i++) {
            int du = tasks[i][2];
            int l = tasks[i][0], r = tasks[i][1];
                for (int j = l; j <= r; j++) {
                    if (d[j] == 1) du--;
                }
                    for (int j = r; du > 0; j--) {
                        if (d[j]) continue;
                        d[j] = 1; du--; ans++;
                    }
        }
        return ans;
    }
    static bool cmp(vector<int> a, vector<int> b) {
        return a[1] < b[1];
    }
};

leecode 1953

在这里插入图片描述
看到题目的数据范围就知道不能暴力算
稍微模拟一下就知道答案

class Solution {
public:
    long long numberOfWeeks(vector<int>& milestones) {
        int len = milestones.size();
        if(len==1) return 1;
        sort(milestones.begin(),milestones.end());
        long long qian = 0;
        for(int i=0;i<len-1;i++) qian+=milestones[i];
        long long ma = milestones[len-1];
        if(qian>=ma) return qian+ma;
        else return qian*2+1;
    }
};

leecode 2644

在这里插入图片描述

class Solution {
public:
    int maxDivScore(vector<int>& nums, vector<int>& divisors) {
        unordered_map<int, int> mp;
        for (int u : divisors) {
            int flag = 0;
            if (mp.contains(u)) continue;    // 避免重复
            if (!u) mp[u] = 0;
            else {
                for (int t : nums) {
                    if (t % u == 0) mp[u]++,flag = 1;
                }
            }
            if (flag == 0) mp[u] = 0;  // 避免没有初始化
        }
        int ans = -1, record = 10000;
        for (auto u : mp) {
            if (u.second > ans) {
                record = u.first;
                ans = u.second;
            }
            else if (u.second == ans) {
                record = min(record, u.first);
            }
        }
        return record;
    }
};

leecode 1535

在这里插入图片描述
我一开是想开两倍空间,然后用单调栈来记录每个值后面有多少个比它小的,但是没有考虑k的问题

class Solution {
public:
    int getWinner(vector<int>& arr, int k) {
        int mx = arr[0], win = 0;
        for (int i = 1; i < arr.size() && win < k; i++) {
            if (arr[i] > mx) { // 新的最大值
                mx = arr[i];
                win = 0;
            }
            win++; // 获胜回合 +1
        }
        return mx;
    }
};
class Solution:
    def getWinner(self, arr: List[int], k: int) -> int:
        mx = arr[0]
        win = -1  # 对于 arr[0] 来说,需要连续 k+1 个回合都是最大值
        for x in arr:
            if x > mx:  # 新的最大值
                mx = x
                win = 0
            win += 1  # 获胜回合 +1
            if win == k:
                break
        return mx

leecode 2225

在这里插入图片描述

以后和桶相关的都不必开数组,开个哈希表就行

class Solution {
public:
    vector<vector<int>> findWinners(vector<vector<int>>& matches) {
        int n = matches.size();
        unordered_map<int, int> mp;
        for (int i = 0; i < n; i++) {
            int win = matches[i][0], lose = matches[i][1];
            if (mp[win] % 2 == 0) {
                mp[win] += 2;
            }
            if (mp[lose]!=-1) {
                if(mp[lose] % 2)
                mp[lose] = -1;
                else {
                    mp[lose] += 1;
                }
            }
        }
        vector<vector<int>> ans(2);
        for (auto u : mp) {
            if (u.second %2==0 && u.second!=0) {
                ans[0].push_back(u.first);
            }
            if (u.second % 2 && u.second != -1) {
                ans[1].push_back(u.first);
            }
        }
        sort(ans[0].begin(), ans[0].end());
        sort(ans[1].begin(), ans[1].end());
        return ans;
    }
};

leecode1673

在这里插入图片描述

第一眼看的时候感觉要用贪心算法,每次找到一个最小的

class Solution {
public:
    vector<int> mostCompetitive(vector<int>& nums, int k) {
        int m = 0; // 栈的大小
        for (int i = 0; i < nums.size(); i++) {
            int x = nums[i];
            while (m && x < nums[m - 1] && m + nums.size() - i > k) {
                m--; // 出栈
            }
            if (m < k) {
                nums[m++] = x; // 入栈(把 nums 当作栈)
            }
        }
        nums.resize(m);
        return nums;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wniuniu_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值