没有标题的博客

2022-12-4 星期日

星期日有什么捏,那必然是力扣周赛了。

因为最后一题不会写,所以就没有写最后一题的题解(这样看来打铁是有原因的)。

示例 1:回环句

输入:sentence = "leetcode exercises sound delightful"
输出:true
解释:句子中的单词是 ["leetcode", "exercises", "sound", "delightful"] 。
- leetcode 的最后一个字符和 exercises 的第一个字符相等。
- exercises 的最后一个字符和 sound 的第一个字符相等。
- sound 的最后一个字符和 delightful 的第一个字符相等。
- delightful 的最后一个字符和 leetcode 的第一个字符相等。
这个句子是回环句。
示例 2:

输入:sentence = "eetcode"
输出:true
解释:句子中的单词是 ["eetcode"] 。
- eetcode 的最后一个字符和 eetcode 的第一个字符相等。
这个句子是回环句。
示例 3:

输入:sentence = "Leetcode is cool"
输出:false
解释:句子中的单词是 ["Leetcode", "is", "cool"] 。
- Leetcode 的最后一个字符和 is 的第一个字符 不 相等。 
这个句子 不 是回环句。
 

提示:

1 <= sentence.length <= 500
sentence 仅由大小写英文字母和空格组成
sentence 中的单词由单个空格进行分隔
不含任何前导或尾随空格

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/circular-sentence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:

  • 很明显,先记录一下首个单词的字符,然后最后一个字符的最后一个字符要进行匹配。
  • 其次,毎相邻的字符串之间,首位要对应。可以理解为,毎当出现一个空格,空格前后的字符要相等

所以,根据这两点,可以开始写代码了。

class Solution {
public:
    bool isCircularSentence(string sentence) {
        char x=sentence[0];
        for(int i=1;i<sentence.length();i++){
            if(i==sentence.length()-1){
                if(sentence[i]!=x){
                    return false;
                }
            }
            else{
                if(sentence[i]==' '){
                    if(sentence[i-1]!=sentence[i+1]){
                        return false;
                    }
                }
            }
        }
        return true;
    }
};

第二题:划分技能点相等的团队

给你一个正整数数组 skill ,数组长度为 偶数 n ,其中 skill[i] 表示第 i 个玩家的技能点。将所有玩家分成 n / 2 个 2 人团队,使每一个团队的技能点之和 相等 。

团队的 化学反应 等于团队中玩家的技能点 乘积 。

返回所有团队的 化学反应 之和,如果无法使每个团队的技能点之和相等,则返回 -1 。

示例 1:

输入:skill = [3,2,5,1,3,4]
输出:22
解释:
将玩家分成 3 个团队 (1, 5), (2, 4), (3, 3) ,每个团队的技能点之和都是 6 。
所有团队的化学反应之和是 1 * 5 + 2 * 4 + 3 * 3 = 5 + 8 + 9 = 22 。
示例 2:

输入:skill = [3,4]
输出:12
解释:
两个玩家形成一个团队,技能点之和是 7 。
团队的化学反应是 3 * 4 = 12 。
示例 3:

输入:skill = [1,1,2,3]
输出:-1
解释:
无法将玩家分成每个团队技能点都相等的若干个 2 人团队。
 

提示:

2 <= skill.length <= 105
skill.length 是偶数
1 <= skill[i] <= 1000

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/divide-players-into-teams-of-equal-skill
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:

  • 因为要把数组里面的n个元素分成n/2组。
  • 而且每组的两个数之和要相等。
  • n为偶数

这个构造的大致意思就是说,

如果最小的不和最大的匹配,那么最大的和一个比最小数更大的数匹配,就会导致技能点之和不相等。

因此最小的一定和最大的匹配。

所以可以直接进行排序,然后遍历即可。

class Solution {
public:
    long long dividePlayers(vector<int>& skill) {
        sort(skill.begin(),skill.end());
        int n=skill.size();
        set<int>p;
        for(int i=0;i<n/2;i++)
            p.insert(skill[i]+skill[n-i-1]);
        if(p.size()>1)
            return -1;
        else{
            long long ans=0;
            for(int i=0;i<n/2;i++)
                ans+=skill[i]*skill[n-i-1];
            return ans;
        }
    }
};

用了一个集合来判断每组之和是否唯一。

第三题:两个城市间路径的最小分数

给你一个正整数 n ,表示总共有 n 个城市,城市从 1 到 n 编号。给你一个二维数组 roads ,其中 roads[i] = [ai, bi, distancei] 表示城市 ai 和 bi 之间有一条 双向 道路,道路距离为 distancei 。城市构成的图不一定是连通的。

两个城市之间一条路径的 分数 定义为这条路径中道路的 最小 距离。

城市 1 和城市 n 之间的所有路径的 最小 分数。

注意:

一条路径指的是两个城市之间的道路序列。
一条路径可以 多次 包含同一条道路,你也可以沿着路径多次到达城市 1 和城市 n 。
测试数据保证城市 1 和城市n 之间 至少 有一条路径。
 

示例 1:

输入:n = 4, roads = [[1,2,9],[2,3,6],[2,4,5],[1,4,7]]
输出:5


解释:城市 1 到城市 4 的路径中,分数最小的一条为:1 -> 2 -> 4 。这条路径的分数是 min(9,5) = 5 。
不存在分数更小的路径。
示例 2:

输入:n = 4, roads = [[1,2,2],[1,3,4],[3,4,7]]
输出:2


解释:城市 1 到城市 4 分数最小的路径是:1 -> 2 -> 1 -> 3 -> 4 。这条路径的分数是 min(2,2,4,7) = 2 。

提示:

2 <= n <= 105
1 <= roads.length <= 105
roads[i].length == 3
1 <= ai, bi <= n
ai != bi
1 <= distancei <= 104
不会有重复的边。
城市 1 和城市 n 之间至少有一条路径。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-score-of-a-path-between-two-cities
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一眼,‘两个城市间路径’,想到了图

第二眼,‘最小分路’,想到了最短路

然后再看题目,

先想到了bfs,记录最短。

但是突然想到,只要一个点跟起点和终点都处于一个联通块上(废话,起点和终点肯定是一个联通块),那么就可以认为这个边有作为一个最小分路的可能。

然后就变成了,可以遍历每条边(也可以优化),然后判断跟起点和终点是不是在一个联通分量就可以了。所以就变成了,先遍历一遍构造联通块,然后再遍历一遍来判断这个边能不能是最小分路,能的话再判断能不能是最小分路。

class Solution {
public:
    vector<int>p;
    int find(int x){
        if(p[x]==x)
            return x;
        else{
            p[x]=find(p[x]);
            return p[x];
        }
    };
    int minScore(int n, vector<vector<int>>& roads) {
        for(int i=0;i<=n;i++)
            p.push_back(i);
        for(int i=0;i<roads.size();i++){
            int x=roads[i][0];
            int y=roads[i][1];
            int a=find(x);
            int b=find(y);
            if(a!=b){
                p[a]=y;
            }
        }
        int m=9999999;
        for(int i=0;i<roads.size();i++){
            int x=roads[i][0];
            int y=roads[i][1];
            int z=roads[i][2];
            if(find(x)==find(1))
                m=min(m,z);
        }
        return m;
    }
};

博客结束。

最后是希望学算法的都能坚持下去,别放弃了(受到不可抗力因素的话就算了)。

/**
 * code generated by cricie
 * @author cricie
 *
 */

/*
 [[ ⣇⣿⠘⣿⣿⣿⡿⡿⣟⣟⢟⢟⢝⠵⡝⣿⡿⢂⣼⣿⣷⣌⠩⡫⡻⣝⠹⢿⣿⣷ ]],
 [[ ⡆⣿⣆⠱⣝⡵⣝⢅⠙⣿⢕⢕⢕⢕⢝⣥⢒⠅⣿⣿⣿⡿⣳⣌⠪⡪⣡⢑⢝⣇ ]],
 [[ ⡆⣿⣿⣦⠹⣳⣳⣕⢅⠈⢗⢕⢕⢕⢕⢕⢈⢆⠟⠋⠉⠁⠉⠉⠁⠈⠼⢐⢕⢽ ]],
 [[ ⡗⢰⣶⣶⣦⣝⢝⢕⢕⠅⡆⢕⢕⢕⢕⢕⣴⠏⣠⡶⠛⡉⡉⡛⢶⣦⡀⠐⣕⢕ ]],
 [[ ⡝⡄⢻⢟⣿⣿⣷⣕⣕⣅⣿⣔⣕⣵⣵⣿⣿⢠⣿⢠⣮⡈⣌⠨⠅⠹⣷⡀⢱⢕ ]],
 [[ ⡝⡵⠟⠈⢀⣀⣀⡀⠉⢿⣿⣿⣿⣿⣿⣿⣿⣼⣿⢈⡋⠴⢿⡟⣡⡇⣿⡇⡀⢕ ]],
 [[ ⡝⠁⣠⣾⠟⡉⡉⡉⠻⣦⣻⣿⣿⣿⣿⣿⣿⣿⣿⣧⠸⣿⣦⣥⣿⡇⡿⣰⢗⢄ ]],
 [[ ⠁⢰⣿⡏⣴⣌⠈⣌⠡⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣬⣉⣉⣁⣄⢖⢕⢕⢕ ]],
 [[ ⡀⢻⣿⡇⢙⠁⠴⢿⡟⣡⡆⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣵⣵⣿ ]],
 [[ ⡻⣄⣻⣿⣌⠘⢿⣷⣥⣿⠇⣿⣿⣿⣿⣿⣿⠛⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ ]],
 [[ ⣷⢄⠻⣿⣟⠿⠦⠍⠉⣡⣾⣿⣿⣿⣿⣿⣿⢸⣿⣦⠙⣿⣿⣿⣿⣿⣿⣿⣿⠟ ]],
 [[ ⡕⡑⣑⣈⣻⢗⢟⢞⢝⣻⣿⣿⣿⣿⣿⣿⣿⠸⣿⠿⠃⣿⣿⣿⣿⣿⣿⡿⠁⣠ ]],
 [[ ⡝⡵⡈⢟⢕⢕⢕⢕⣵⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣿⣿⣿⣿⣿⠿⠋⣀⣈⠙ ]],
 [[ ⡝⡵⡕⡀⠑⠳⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢉⡠⡲⡫⡪⡪⡣ ]],
  */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值