LeetCode第128场双周赛题解

3110.字符串的分数

给你一个字符串 s 。一个字符串的 分数 定义为相邻字符 ASCII 码差值绝对值的和。

请你返回 s 的 分数 。

示例 1:

输入:s = "hello"

输出:13

解释:

s 中字符的 ASCII 码分别为:'h' = 104 ,'e' = 101 ,'l' = 108 ,'o' = 111 。所以 s 的分数为 |104 - 101| + |101 - 108| + |108 - 108| + |108 - 111| = 3 + 7 + 0 + 3 = 13 。

示例 2:

输入:s = "zaz"

输出:50

解释:

s 中字符的 ASCII 码分别为:'z' = 122 ,'a' = 97 。所以 s 的分数为 |122 - 97| + |97 - 122| = 25 + 25 = 50 。

提示:

  • 2 <= s.length <= 100
  • s 只包含小写英文字母。

没啥好说的,挺简单的。两三分钟拿下

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int scoreOfString(string s) {
     int ans=0;
     int n=s.length();
     for(int i=0;i<=n-2;i++){
        // cout<<abs(s[i]-s[i+1])<<endl;
        ans+=abs(s[i]-s[i+1]);
     }   
     return ans;

}
int main(){
    string s="hello";
    cout<<scoreOfString(s)<<endl;
    return 0;
}

3111、覆盖所有点的最少矩形数目

给你一个二维整数数组 point ,其中 points[i] = [xi, yi] 表示二维平面内的一个点。同时给你一个整数 w 。你需要用矩形 覆盖所有 点。

每个矩形的左下角在某个点 (x1, 0) 处,且右上角在某个点 (x2, y2) 处,其中 x1 <= x2 且 y2 >= 0 ,同时对于每个矩形都 必须 满足 x2 - x1 <= w 。

如果一个点在矩形内或者在边上,我们说这个点被矩形覆盖了。

请你在确保每个点都 至少 被一个矩形覆盖的前提下,最少 需要多少个矩形。

注意:一个点可以被多个矩形覆盖。

示例 1:

输入:points = [[2,1],[1,0],[1,4],[1,8],[3,5],[4,6]], w = 1

输出:2

解释:

上图展示了一种可行的矩形放置方案:

  • 一个矩形的左下角在 (1, 0) ,右上角在 (2, 8) 。
  • 一个矩形的左下角在 (3, 0) ,右上角在 (4, 8) 。

示例 2:

输入:points = [[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]], w = 2

输出:3

解释:

上图展示了一种可行的矩形放置方案:

  • 一个矩形的左下角在 (0, 0) ,右上角在 (2, 2) 。
  • 一个矩形的左下角在 (3, 0) ,右上角在 (5, 5) 。
  • 一个矩形的左下角在 (6, 0) ,右上角在 (6, 6) 。

示例 3:

输入:points = [[2,3],[1,2]], w = 0

输出:2

解释:

上图展示了一种可行的矩形放置方案:

  • 一个矩形的左下角在 (1, 0) ,右上角在 (1, 2) 。
  • 一个矩形的左下角在 (2, 0) ,右上角在 (2, 3) 。

提示:

  • 1 <= points.length <= 105
  • points[i].length == 2
  • 0 <= xi == points[i][0] <= 109
  • 0 <= yi == points[i][1] <= 109
  • 0 <= w <= 109
  • 所有点坐标 (xi, yi) 互不相同。

这个题很明显只需要考虑横坐标,使用set,排序去重

遍历一遍,x1,x2;如果x2-x1>w,那就再次开始:使x1=x2,更新左边界,同时ans++

所以时间复杂度:O(N),空间复杂度:O(N+2)

#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
int minRectanglesToCoverPoints(vector<vector<int>>& points, int w) {
    set<int> xs;
    for (auto& p : points) {
        xs.insert(p[0]);
    }

    vector<int> sorted_xs(xs.begin(), xs.end());

    int ans = 0;
    int x1 = sorted_xs[0];

    for (int i = 1; i < sorted_xs.size(); i++) {
        int x2 = sorted_xs[i];
        if (x2 - x1 > w) {
            ans++;
            x1 = x2;
        }
    }

    return ans + 1; // Add 1 for the last rectangle

}
int main(){
    // :points = [[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]], w = 2
    vector<vector<int>> points={{3,1},{5,7},{4,1}};
    int w=1;
    cout<<minRectanglesToCoverPoints(points,w)<<endl;
    return 0;

}
    

3112.访问消失节点的最少时间

给你一个二维数组 edges 表示一个 n 个点的无向图,其中 edges[i] = [ui, vi, lengthi] 表示节点 ui 和节点 vi 之间有一条需要 lengthi 单位时间通过的无向边。

同时给你一个数组 disappear ,其中 disappear[i] 表示节点 i 从图中消失的时间点,在那一刻及以后,你无法再访问这个节点。

注意,图有可能一开始是不连通的,两个节点之间也可能有多条边。

请你返回数组 answer ,answer[i] 表示从节点 0 到节点 i 需要的 最少 单位时间。如果从节点 0 出发 无法 到达节点 i ,那么 answer[i] 为 -1 。

示例 1:

输入:n = 3, edges = [[0,1,2],[1,2,1],[0,2,4]], disappear = [1,1,5]

输出:[0,-1,4]

解释:

我们从节点 0 出发,目的是用最少的时间在其他节点消失之前到达它们。

  • 对于节点 0 ,我们不需要任何时间,因为它就是我们的起点。
  • 对于节点 1 ,我们需要至少 2 单位时间,通过 edges[0] 到达。但当我们到达的时候,它已经消失了,所以我们无法到达它。
  • 对于节点 2 ,我们需要至少 4 单位时间,通过 edges[2] 到达。

示例 2:

输入:n = 3, edges = [[0,1,2],[1,2,1],[0,2,4]], disappear = [1,3,5]

输出:[0,2,3]

解释:

我们从节点 0 出发,目的是用最少的时间在其他节点消失之前到达它们。

  • 对于节点 0 ,我们不需要任何时间,因为它就是我们的起点。
  • 对于节点 1 ,我们需要至少 2 单位时间,通过 edges[0] 到达。
  • 对于节点 2 ,我们需要至少 3 单位时间,通过 edges[0] 和 edges[1] 到达。

示例 3:

输入:n = 2, edges = [[0,1,1]], disappear = [1,1]

输出:[0,-1]

解释:

当我们到达节点 1 的时候,它恰好消失,所以我们无法到达节点 1 。

提示:

  • 1 <= n <= 5 * 104
  • 0 <= edges.length <= 105
  • edges[i] == [ui, vi, lengthi]
  • 0 <= ui, vi <= n - 1
  • 1 <= lengthi <= 105
  • disappear.length == n
  • 1 <= disappear[i] <= 105
这是一道模板题,
只需要在 Dijkstra 算法的基础上,添加一处判断逻辑,在更新最短路之前,如果最短路长度 >=disappear[i]则不更新。

#include <iostream>
#include <vector>
// #include <priority_queue>
#include <queue>
#include <map>
using namespace std;
vector<int> minimumTime(int n, vector<vector<int>>& edges, vector<int>& disappear) {
     vector<vector<pair<int, int>>>g(n);
     for(auto& e:edges){   //稀疏矩阵
        int x=e[0],y=e[1],wt=e[2];
        g[x].emplace_back(y,wt);
        g[y].emplace_back(x,wt);

     }
     vector<int> dis(n,-1);
     dis[0]=0;
     priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
     pq.emplace(0,0);
     while(!pq.empty()) {
      auto[dx,x]=pq.top();
      pq.pop();
      if(dx>dis[x]){
         continue;
      }
      for(auto& [y,d]:g[x]) {
         int new_dis=dx+d;
         if(new_dis<disappear[y] && dis[y]<0||new_dis<dis[y]){
            dis[y]=new_dis;   //更新x的邻居的最短路
            pq.emplace(new_dis,y);
         }
      }
     }
     return dis;

}

3113.边界元素是最大值的子数组数目

给你一个  整数数组 nums 。

请你求出 nums 中有多少个子数组,满足子数组中 第一个 和 最后一个 元素都是这个子数组中的 最大 值。

示例 1:

输入:nums = [1,4,3,3,2]

输出:6

解释:

总共有 6 个子数组满足第一个元素和最后一个元素都是子数组中的最大值:

  • 子数组 [1,4,3,3,2] ,最大元素为 1 ,第一个和最后一个元素都是 1 。
  • 子数组 [1,4,3,3,2] ,最大元素为 4 ,第一个和最后一个元素都是 4 。
  • 子数组 [1,4,3,3,2] ,最大元素为 3 ,第一个和最后一个元素都是 3 。
  • 子数组 [1,4,3,3,2] ,最大元素为 3 ,第一个和最后一个元素都是 3 。
  • 子数组 [1,4,3,3,2] ,最大元素为 2 ,第一个和最后一个元素都是 2 。
  • 子数组 [1,4,3,3,2] ,最大元素为 3 ,第一个和最后一个元素都是 3 。

所以我们返回 6 。

示例 2:

输入:nums = [3,3,3]

输出:6

解释:

总共有 6 个子数组满足第一个元素和最后一个元素都是子数组中的最大值:

  • 子数组 [3,3,3] ,最大元素为 3 ,第一个和最后一个元素都是 3 。
  • 子数组 [3,3,3] ,最大元素为 3 ,第一个和最后一个元素都是 3 。
  • 子数组 [3,3,3] ,最大元素为 3 ,第一个和最后一个元素都是 3 。
  • 子数组 [3,3,3] ,最大元素为 3 ,第一个和最后一个元素都是 3 。
  • 子数组 [3,3,3] ,最大元素为 3 ,第一个和最后一个元素都是 3 。
  • 子数组 [3,3,3] ,最大元素为 3 ,第一个和最后一个元素都是 3 。

所以我们返回 6 。

示例 3:

输入:nums = [1]

输出:1

解释:

nums 中只有一个子数组 [1] ,最大元素为 1 ,第一个和最后一个元素都是 1 。

所以我们返回 1 。

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109

感觉和那个天气预测还有接雨水差不多,使用单调栈

#include<iostream>
#include<vector>
#include<stack>
#include<map>
using namespace std;
long long numberOfSubarrays(vector<int>& nums) {
    long long ans=nums.size();  //初始化,最少nums.size()个
    stack<pair<int,int>>st;
    st.emplace(INT_MAX,0);  //无穷大
    for(int x:nums) {
        while(x>st.top().first){   //如果大于栈顶,
            st.pop();
        }
        if(x==st.top().first){
            ans+=st.top().second++;
        } else {           //如果 x小于栈顶,把 x及其出现次数 1 入栈
            st.emplace(x,1);
        }
    }
    return ans;

}
int main(){
    vector<int>nums = {1,4,3,3,2};
    cout<<numberOfSubarrays(nums);
    return 0;
}

739.每日温度

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例 3:

输入: temperatures = [30,60,90]
输出: [1,1,0]

提示:

  • 1 <= temperatures.length <= 105
  • 30 <= temperatures[i] <= 100
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
vector<int> dailyTemperatures(vector<int>& temperatures) {
    int n=temperatures.size();
    vector<int> ans(n,0);
    stack<int> st;
    for(int i=0;i<n;i++){
        int t = temperatures[i];
        while(!st.empty() && t>temperatures[st.top()]) {
            int j=st.top();
            st.pop();
            ans[j]=i-j;
        
        }
        st.push(i);
    }
    return ans;
}
int main(){
    vector<int>temperatures = {73,74,75,71,69,72,76,73};
    vector<int>ans{dailyTemperatures(temperatures)};
    for(int i=0;i<temperatures.size();i++){
        cout<<ans[i]<<" ";
    }
    return 0;
}

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值