检查句子中的数字是否递增
题目描述:力扣 5902.检查句子中的数字是否递增
解题思路:
遍历一遍字符串,p代表前值,n代表后值,随着遍历,p和n不断变化;并判断:
当n<=p时,false
代码
class Solution
{
public:
bool areNumbersAscending(string s) {
int i;
int p=0;
int n=0;
for(i=0;i<s.length();i++)
{
if(s[i]>='0'&&s[i]<='9')
{
int num=s[i]-'0';
n=n*10+num;
}
else
{
if(n){
if(n<=p)
return false;
p=n;
}
n=0;
}
}
if(n!=0&&n<=p)
return false;
return true;
}
};
简易银行系统
题目描述:力扣 2043 简易银行系统
代码
class Bank
{
public:
vector<long long> nums;
int n;
Bank(vector<long long>& balance)
{
this->nums = balance;
this->n = (int)balance.size();
}
bool withdraw(int account, long long money) //取款
{
int x = account - 1;
if (0 <= x && x < n && nums[x] >= money)
{
nums[x] -= money;
return true;
}
return false;
}
bool transfer(int account1, int account2, long long money) //转账,account1取钱,account2存钱
{
int x = account1 - 1;
int y = account2 - 1;
if (0 <= x && x < n && 0 <= y && y < n && nums[x] >= money)
{
nums[x] -= money;
nums[y] += money;
return true;
}
return false;
}
bool deposit(int account, long long money) //存款
{
int x = account - 1;
if (0 <= x && x < n)
{
nums[x] += money;
return true;
}
return false;
}
};
统计按位或能得到最大值的子集数目
题目描述:力扣 2044 统计按位或能得到最大值的子集数目
代码
class Solution {
public:
int ans = 0;
int countMaxOrSubsets(vector<int>& nums) {
// 按位或是不减的操作,所以全部 | 起来是最大值
int max = 0;
for(auto p : nums){
max |= p; //循环按位异或求nums最大值
}
dfs(nums, max, 0, 0);
return ans;
}
void dfs(vector<int>& nums, int& m, int idx, int cur){ //cur是子集按位异或的最大值
// 剪枝
if(cur == m){
ans += 1 << (nums.size() - idx); //ans是子集个数
return;
}
if(idx == nums.size()){ //idex是下标
return;
}
dfs(nums, m, idx + 1, cur | nums[idx]); //加这个数
dfs(nums, m, idx + 1, cur); // 不加这个数
}
};
到达目的地的第二短时间
题目描述:力扣 2045 到达目的地的第二短时间
解题思路
由于每个点可以重复到达,因此深度优先搜索肯定是用不了的,要使用广度优先搜索(数据结构:队列)
每次搜索时,先检查能否从当前点出发,如果不能(红灯),则修改时间为绿灯亮时
对于每一个当前点的邻接点,加上走边的时间,并入队列。如果当前点是n,则判断是不是第一次达到。如果是,记录下来,如果不是,则看这次的时间有没有比上一次慢,如果相等则还要继续搜索。
由于如果对遇到的每一个节点都入队列,会造成超时,因此这里我们使用剪枝的方法。首先,判断是不是第一次到达这一个点,如果是的话就记录下来并入队列,继续搜索。如果不是,则看是不是第二次到达,并且这次时间要慢于最快到达的时间,如果满足则入队列,继续搜索。显然,最终的结果下所走过的路径一定是第二次所记录到的路径。
代码
class Solution {
public:
int secondMinimum(int n, vector<vector<int>>& edges, int time, int change) {
unordered_map<int, vector<int>> e;//邻接表
for(int i = 0; i < edges.size(); ++i){
if(e.find(edges[i][0]) == e.end()){
e[edges[i][0]] = vector<int>();
}
if(e.find(edges[i][1]) == e.end()){
e[edges[i][1]] = vector<int>();
}
e[edges[i][0]].push_back(edges[i][1]);
e[edges[i][1]].push_back(edges[i][0]);
}
deque<pair<int, int>> q;
q.push_back(pair<int, int>(1, 0));
unordered_map<int, int> fir;
unordered_map<int, int> sec;
int min_time = -1;
while(q.size() > 0){
int num = q.size();
for(int j = 0; j < num; ++j){
int cur = q.front().first;
int now = q.front().second;
q.pop_front();
if((now / change) % 2 == 1){
now = now - (now % change) + change;
}
for(auto i: e[cur]){
if(i == n){
if(min_time != -1 && min_time != (now + time)){
return now + time;
}
min_time = now + time;
}
if(fir.find(i) == fir.end()){ //看看是不是第一次到达改点,如果是的话记录到达改点最快的时间,并入队列
fir[i] = now + time;
q.push_back(pair<int, int>(i, now + time));
continue;
}
if(sec.find(i) == sec.end() && fir[i] < now + time){ //看看是不是第二次到达改点,并且第二次的时间比第一次长(而不是等于),如果满足则记录第二快时间,并入队列
sec[i] = now + time;
q.push_back(pair<int, int>(i, now + time));
}
}
}
}
return 0;
}
};