2022-02-18每日刷题打卡

140 阅读5分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

2022-02-18每日刷题打卡

力扣——每日一题

1791. 找出星型图的中心节点

有一个无向的 星型 图,由 n 个编号从 1 到 n 的节点组成。星型图有一个 中心 节点,并且恰有 n - 1 条边将中心节点与其他每个节点连接起来。

给你一个二维整数数组 edges ,其中 edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间存在一条边。请你找出并返回 edges 所表示星型图的中心节点。

示例 1:

star_graph.png (331×321) (leetcode-cn.com)

输入:edges = [[1,2],[2,3],[4,2]]
输出:2
解释:如上图所示,节点 2 与其他每个节点都相连,所以节点 2 是中心节点。

借用评论区的一句话说,这种题放在简单里也是耻辱的。

可能一开始想着是哈希表记录所有点的出现次数,出现次数最大的就是心节点。但其实不用那么复杂,这题完全可以做到时间和空间都是O1,只用比较前两个数对,找出相同的那个点就行了,因为这个数对只有两个数,而且每个数对里都会有一个心节点,那么只要找出相同的那个就行了。

class Solution {
public:
    int findCenter(vector<vector<int>>& edges) {
        return edges[0][0]==edges[1][0]?edges[0][0]:edges[0][0]==edges[1][1]?edges[0][0]:edges[0][1];
    }
};

329. 矩阵中的最长递增路径

给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。

对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。

示例 1:

grid1.jpg (242×242) (leetcode.com)

输入:matrix = [[9,9,4],[6,6,8],[2,1,1]]
输出:4
解释:最长递增路径为 [1, 2, 6, 9]。

每次以矩阵的一个点为起点深度搜索,准备一个和所给矩阵一样大小的数组f,每次吧深搜的结果存入数组中,下标为起点的下标。这样,当后面的点深搜到这里时,我们就知道从这个点出发还能走多长,直接把这个结果加到我们当前的深搜结果中即可。

class Solution {
public:
    int f[210][210];
    int n,m;
    int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        n=matrix.size(),m=matrix[0].size();
        int res=0;
        memset(f,-1,sizeof f);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                dfs(i,j,matrix);
                res=max(res,f[i][j]);
            }
        }
        return res;
    }
    int dfs(int x,int y,vector<vector<int>>& matrix)
    {
        if(f[x][y]!=-1)return f[x][y];
        f[x][y]=1;
        for(int i=0;i<4;i++)
        {
            int a=x+dx[i],b=y+dy[i];
            if(a>=0&&a<n&&b>=0&&b<m&&matrix[a][b]>matrix[x][y])
            {
                f[x][y]=max(dfs(a,b,matrix)+1,f[x][y]);
            }
        }
        return f[x][y];
    }
};

1387. 将整数按权重排序

我们将整数 x 的 权重 定义为按照下述规则将 x 变成 1 所需要的步数:

如果 x 是偶数,那么 x = x / 2
如果 x 是奇数,那么 x = 3 * x + 1
比方说,x=3 的权重为 7 。因为 3 需要 7 步变成 1 (3 --> 10 --> 5 --> 16 --> 8 --> 4 --> 2 --> 1)。

给你三个整数 lo, hi 和 k 。你的任务是将区间 [lo, hi] 之间的整数按照它们的权重 升序排序 ,如果大于等于 2 个整数有 相同 的权重,那么按照数字自身的数值 升序排序 。

请你返回区间 [lo, hi] 之间的整数按权重排序后的第 k 个数。

注意,题目保证对于任意整数 x (lo <= x <= hi) ,它变成 1 所需要的步数是一个 32 位有符号整数。

示例 1:

输入:lo = 12, hi = 15, k = 2
输出:13
解释:12 的权重为 9(12 --> 6 --> 3 --> 10 --> 5 --> 16 --> 8 --> 4 --> 2 --> 1)
13 的权重为 9
14 的权重为 17
15 的权重为 17
区间内的数按权重排序以后的结果为 [12,13,14,15] 。对于 k = 2 ,答案是第二个整数也就是 13 。
注意,12 和 13 有相同的权重,所以我们按照它们本身升序排序。14 和 15 同理。

记忆化搜索,准备一个长度1000的数组f,f[i]的意思是,数为i,按照题目所给规则变成1的步骤为f[i].开始循环,从1循环到hi,每次送循环到的数去深搜:数为奇数时x=3*x+1,偶数时x=x/2; 每进行一次操作后记录步骤的计数器++,当x=1时,在f的对应位置上把计数器记录的步骤赋值过去。准备f数组就是为了把走过的位置的权都记录下来,这样后面的数经过变化到达这个位置时,就可以直接知道之后还有多少步骤了,比如3变成1要7步,12变成3要2步,当到达3时我们知道,只用在变换7次就可以变成1了,那我们直接给12的计数器+7即可。这就是记忆化搜索。然后准备一个数对数组,数对头是lo~hi,数对尾是对应的权重,然后对其排序,取出第k大的数返回。

class Solution {
public:
    typedef pair<int, int>PII;
    vector<int>v;
    static bool cmp(PII a, PII b)
    {
        if (a.second != b.second)
            return a.second < b.second;
        return a < b;
    }
    void dfs(int y,int x, int ans)
    {
        if (x<=1000&&v[x] != -1)
        {
            v[y]=ans+v[x];
        }
        else if (x == 1)
        {
            v[y]=ans;
            return ;
        }
        else if (x % 2) dfs(y,3 * x + 1, ans + 1);
        else dfs(y,x / 2, ans + 1);
    }
    int getKth(int lo, int hi, int k) {
        vector<int>v1(3005,-1);
        v=v1;
        vector<PII>p;
        for (int i = 1; i <= hi; i++)
        {
            dfs(i,i, 0);
        }
        for (int i = lo; i <= hi; i++)
        {
            p.push_back({ i,v[i] });
        }
        
        sort(p.begin(),p.end(), cmp);
        return p[k - 1].first;
    }
};

蓝桥杯——算法提高

算法提高 字符串进位

问题描述

对字符串中每一位替换为它的后继字符,然后输出。

输入格式

一行N个a~y的字母。

输出格式

一行N个字母表示答案。

样例输入

abcd

样例输出

bcde

数据规模和约定

N<=100000。

提示

请教小教员:如何使用string;或者以char的形式读入,如while (cin>>ch){}会读进来每一个字符直到结束。

用string接收,然后把每一个字符+1后输出。

#include<iostream>
using namespace std;
int main()
{
	string str;
	cin >> str;
	for (int i = 0; i < str.size(); i++)
	{
		char c = str[i] + 1;
		cout << c;
	}
	return 0;
}