【力扣周赛】第347场周赛

news2024/12/22 19:00:45

【力扣周赛】第347场周赛

    • 6457. 移除字符串中的尾随零
      • 题目描述
      • 解题思路
    • 2711. 对角线上不同值的数量差
      • 题目描述
      • 解题思路
    • 6455. 使所有字符相等的最小成本
      • 题目描述
      • 解题思路
    • 6456. 矩阵中严格递增的单元格数
      • 题目描述
      • 解题思路

6457. 移除字符串中的尾随零

题目描述

描述:给你一个用字符串表示的正整数 num ,请你以字符串形式返回不含尾随零的整数 num 。

示例 1:

输入:num = "51230100"
输出:"512301"
解释:整数 "51230100" 有 2 个尾随零,移除并返回整数 "512301" 。

示例 2:

输入:num = "123"
输出:"123"
解释:整数 "123" 不含尾随零,返回整数 "123" 。

提示:

1 <= num.length <= 1000
num 仅由数字 0 到 9 组成
num 不含前导零

解题思路

难度:简单。

思路:最直观的想法是,从后向前遍历字符串,如果当前为0,则将其从字符串删除。

class Solution {
public:
    string removeTrailingZeros(string num) {
        int n=num.size();
        int i=n-1;
        while(i>=0&&num[i]=='0') 
        {
            num.pop_back();
            i--;
        }
        return num;
    }
};

2711. 对角线上不同值的数量差

题目描述

描述:给你一个下标从 0 开始、大小为 m x n 的二维矩阵 grid ,请你求解大小同样为 m x n 的答案矩阵 answer 。

矩阵 answer 中每个单元格 (r, c) 的值可以按下述方式进行计算:

令 topLeft[r][c] 为矩阵 grid 中单元格 (r, c) 左上角对角线上 不同值 的数量。
令 bottomRight[r][c] 为矩阵 grid 中单元格 (r, c) 右下角对角线上 不同值 的数量。
然后 answer[r][c] = |topLeft[r][c] - bottomRight[r][c]| 。

返回矩阵 answer 。

矩阵对角线 是从最顶行或最左列的某个单元格开始,向右下方向走到矩阵末尾的对角线。

如果单元格 (r1, c1) 和单元格 (r, c) 属于同一条对角线且 r1 < r ,则单元格 (r1, c1) 属于单元格 (r, c) 的左上对角线。类似地,可以定义右下对角线。

示例 1:

在这里插入图片描述

输入:grid = [[1,2,3],[3,1,5],[3,2,1]]
输出:[[1,1,0],[1,0,1],[0,1,1]]
解释:第 1 个图表示最初的矩阵 grid 。 
第 2 个图表示对单元格 (0,0) 计算,其中蓝色单元格是位于右下对角线的单元格。
第 3 个图表示对单元格 (1,2) 计算,其中红色单元格是位于左上对角线的单元格。
第 4 个图表示对单元格 (1,1) 计算,其中蓝色单元格是位于右下对角线的单元格,红色单元格是位于左上对角线的单元格。
- 单元格 (0,0) 的右下对角线包含 [1,1] ,而左上对角线包含 [] 。对应答案是 |1 - 0| = 1 。
- 单元格 (1,2) 的右下对角线包含 [] ,而左上对角线包含 [2] 。对应答案是 |0 - 1| = 1 。
- 单元格 (1,1) 的右下对角线包含 [1] ,而左上对角线包含 [1] 。对应答案是 |1 - 1| = 0 。
其他单元格的对应答案也可以按照这样的流程进行计算。

示例 2:

输入:grid = [[1]]
输出:[[0]]
解释:- 单元格 (0,0) 的右下对角线包含 [] ,左上对角线包含 [] 。对应答案是 |0 - 0| = 0 。

提示:

m == grid.length
n == grid[i].length
1 <= m, n, grid[i][j] <= 50

解题思路

难度:中等。

思路:最直观的想法是,遍历二维矩阵,使用(i,j)表示当前元素坐标,对于每一个元素,使用set集合topleft存储该元素左上角不同值,分别使用(i–,j–)表示当前元素左上角元素坐标,使用set集合bottomright存储该元素右下角不同值,分别使用(i++,j++)表示当前元素右下角元素坐标。

#include<stdlib.h>
class Solution {
public:
    vector<vector<int>> differenceOfDistinctValues(vector<vector<int>>& grid) {
        int m=grid.size();
        int n=grid[0].size();
        vector<vector<int>> res;
        for(int i=0;i<m;i++)
        {
            vector<int> temp;
            for(int j=0;j<n;j++)
            {
                unordered_set<int> topleft;  //左上角不同值
                unordered_set<int> bottomright;  //右下角不同值
                int row=i-1;
                int col=j-1;
                //左上角
                while(row>=0&&col>=0)
                {
                    topleft.insert(grid[row][col]);
                    row--;
                    col--;
                }
                //右下角
                int a=i+1;
                int b=j+1;
                while(a<m&&b<n)
                {
                    bottomright.insert(grid[a][b]);
                    a++;
                    b++;
                }
                int ans=topleft.size()>bottomright.size()?topleft.size()-bottomright.size():bottomright.size()-topleft.size();
                temp.push_back(ans);
            }
            res.push_back(temp);
        }
        return res;
    }
};

6455. 使所有字符相等的最小成本

题目描述

描述:给你一个下标从 0 开始、长度为 n 的二进制字符串 s ,你可以对其执行两种操作:

选中一个下标 i 并且反转从下标 0 到下标 i(包括下标 0 和下标 i )的所有字符,成本为 i + 1 。
选中一个下标 i 并且反转从下标 i 到下标 n - 1(包括下标 i 和下标 n - 1 )的所有字符,成本为 n - i 。
返回使字符串内所有字符 相等 需要的 最小成本 。

反转 字符意味着:如果原来的值是 ‘0’ ,则反转后值变为 ‘1’ ,反之亦然。

示例 1:

输入:s = "0011"
输出:2
解释:执行第二种操作,选中下标 i = 2 ,可以得到 s = "0000" ,成本为 2 。可以证明 2 是使所有字符相等的最小成本。

示例 2:

输入:s = "010101"
输出:9
解释:执行第一种操作,选中下标 i = 2 ,可以得到 s = "101101" ,成本为 3 。
执行第一种操作,选中下标 i = 1 ,可以得到 s = "011101" ,成本为 2 。
执行第一种操作,选中下标 i = 0 ,可以得到 s = "111101" ,成本为 1 。
执行第二种操作,选中下标 i = 4 ,可以得到 s = "111110" ,成本为 2 。
执行第一种操作,选中下标 i = 5 ,可以得到 s = "111111" ,成本为 1 。
使所有字符相等的总成本等于 9 。可以证明 9 是使所有字符相等的最小成本。 

提示:

1 <= s.length == n <= 105
s[i] 为 ‘0’ 或 ‘1’

解题思路

使所有字符相等的最小成本:最直观的想法是,从头到尾遍历字符串,如果当前字符和前一个字符不相等则需要翻转,翻转时选择子字符串[0,i-1]或者[i,n-1]两者中成本最小的,这样可以保证[0,i]部分字符全部相等,[i,n-1]部分翻转后仍不相等,故仍然需要从前向后遍历。

long long minimumCost(string s) 
{
    long long ans=0;
    int n=s.length();
    for(int i=1;i<n;i++)
    {
       if(s[i-1]!=s[i])
       	 //翻转[0,i-1]或者[i,n-1]
         ans+=min(i,n-i);
    }
    return ans;
}

总结:妙啊!题目示例具有迷惑性!

6456. 矩阵中严格递增的单元格数

题目描述

描述:给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat,你可以选择任一单元格作为 起始单元格 。

从起始单元格出发,你可以移动到 同一行或同一列 中的任何其他单元格,但前提是目标单元格的值 严格大于 当前单元格的值。

你可以多次重复这一过程,从一个单元格移动到另一个单元格,直到无法再进行任何移动。

请你找出从某个单元开始访问矩阵所能访问的 单元格的最大数量 。

返回一个表示可访问单元格最大数量的整数。

示例 1:

在这里插入图片描述

输入:mat = [[3,1],[3,4]]
输出:2
解释:上图展示了从第 1 行、第 2 列的单元格开始,可以访问 2 个单元格。可以证明,无论从哪个单元格开始,最多只能访问 2 个单元格,因此答案是 2 。 

示例 2:

在这里插入图片描述

输入:mat = [[1,1],[1,1]]
输出:1
解释:由于目标单元格必须严格大于当前单元格,在本示例中只能访问 1 个单元格。 

示例 3:

在这里插入图片描述

输入:mat = [[3,1,6],[-9,5,7]]
输出:4
解释:上图展示了从第 2 行、第 1 列的单元格开始,可以访问 4 个单元格。可以证明,无论从哪个单元格开始,最多只能访问 4 个单元格,因此答案是 4 。  

提示:

m == mat.length
n == mat[i].length
1 <= m, n <= 105
1 <= m * n <= 105
-105 <= mat[i][j] <= 105

解题思路

难度:难。

思路:最直观的想法是,由于目标单元格严格大于当前单元格,即数值从小往大转移,那么可以使用一个map存储(值,坐标集合),这样得到的集合即为按照数值从小到大排序的集合,其中值相同的为一组。假设dp[i][j]表示到达坐标(i,j)所经过的最大单元格数,那么递推公式为dp[i][j]=max(row_max[i],col_max[j])+1,其中row_max[i]表示第i行最大f值,col_max[j]表示第j列最大f值。遍历map,首先计算同组的dp值,然后更新同组的最大f值,即可。

int maxIncreasingCells(vector<vector<int>>& mat) 
{
   int m=mat.size();
   int n=mat[0].size();
   // 存储结果
   int res=0; 
   // 存储每一行最大f值以及每一列最大f值
   vector<int> row_max(m),col_max(n);
   // <value,[{i1,j1},{i2,j2}...]> 注意 相同值存储在同一组
   map<int,vector<pair<int,int>>> vmap;
   // 注意 相同值存储在同一组
   for(int i=0;i<m;i++)
   {
        for(int j=0;j<n;j++)
        {
           vmap[mat[i][j]].push_back({i,j});
        }
   }
   // map本身有序 故会按照元素值从小到大计算 其中同组的会先计算再更新 比如 3 1 3 4 第一列的两个3计算
   for(auto& [value,pos]:vmap) //&表示可以被改变 []表示接受复杂类型
   {
        vector<int> mx;
        //计算同组的最大f值
        for(auto& [i,j]:pos)
        {
           //dp公式 max(row_max[i],col_max[j])+1 计算当前行与当前列中最大f值 +1表示算当前单元格
           mx.push_back(max(row_max[i],col_max[j])+1);
           res=max(res,mx.back());
        }
        //更新同组的最大f值
        for(int k=0;k<pos.size();k++)
        {
           auto &[i,j]=pos[k];
           row_max[i]=max(row_max[i],mx[k]);
           col_max[j]=max(col_max[j],mx[k]);
           // cout<<"i="<<i<<";j="<<j<<"value="<<value<<";mx["<<k<<"]="<<mx[k]<<";row_max["<<i<<"]="<<row_max[i]<<";col_max["<<j<<"]="<<col_max[j]<<endl;
        }
    }
    return res;
}

错误:一开始,我拿到这个题,感觉比“使所有字符相等的最小成本”那题好想一些,于是琢磨,应该选择从矩阵中最小数值开始出发,然后选择该值所在行或者所在列中尚未访问过的且比该值大的最小值,依次类推,直至不能再移动为止,但是我发现,测试案例[[-1,5,-9],[-2,-5,0]]无法通过,后来一想,那么将选择从矩阵中最小数值开始出发转为从矩阵中任意数值出发,然后统计所有数值出发的所达数量最大值即可,后来发现,测试案例[[3,-8],[8,1],[2,-5]]无法通过,即最后只通过168个测试案例,我就觉得应该是解题思路错误了,不过第一次尝试困难题,第一次能坚持想法写下来,第一次能通过困难题1/3测试案例,我觉得很棒了哈哈哈哈,继续加油啦!

// 一开始的错误写法1 留作纪念
class Solution {
public:
    //寻找最小值所在行或者所在列的相对最小值较大的值
    vector<int> dfs(int& res,vector<vector<int>>& mat,vector<vector<bool>>& visit,int m,int n,int row,int col,int val)
    {
        int minrow=-1;
        int mincol=-1;
        int minval=val;
        map<int,vector<int>> num;
        //行
        for(int i=0;i<n;i++)
        {
            if(!visit[row][i]&&i!=col&&mat[row][i]>val)
            {
                num[mat[row][i]]={row,i};
            }
        }
        //列
        for(int i=0;i<m;i++)
        {
            if(!visit[i][col]&&i!=row&&mat[i][col]>val)
            {
                num[mat[i][col]]={i,col};
            }
        }
        minrow=num.size()?num.begin()->second[0]:-1;
        mincol=num.size()?num.begin()->second[1]:-1;
        minval=num.size()?num.begin()->first:-1;
        if(minrow!=-1&&mincol!=-1)
        {
            visit[minrow][mincol]=true;
            res++;
        }
        return {minrow,mincol,minval};
    }
    int maxIncreasingCells(vector<vector<int>>& mat) {
        int m=mat.size();
        int n=mat[0].size();
        vector<vector<bool>> visit(m,vector<bool>(n,false));
        int res=1; //基础为1
        int minrow=-1;
        int mincol=-1;
        int minval=INT_MAX;
        //寻找最小点作为出发值
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(mat[i][j]<minval)
                {
                    minval=mat[i][j];
                    minrow=i;
                    mincol=j;
                }
            }
        }
        //置访问标志
        visit[minrow][mincol]=true;
        while(minrow!=-1&&mincol!=-1)
        {
            vector<int> temp;
            temp = dfs(res,mat,visit,m,n,minrow,mincol,minval);
            for(auto n:temp)
                cout<<n<<endl;
            minrow = temp[0];
            mincol = temp[1];
            minval = temp[2];
        }
        return res;
    }
};
// 一开始的错误写法2 留作纪念
class Solution {
public:
    //寻找最小值所在行或者所在列的相对最小值较大的值
    vector<int> dfs(int& res,vector<vector<int>>& mat,vector<vector<bool>>& visit,int m,int n,int row,int col,int val)
    {
        int minrow=-1;
        int mincol=-1;
        int minval=val;
        map<int,vector<int>> num;
        //行
        for(int i=0;i<n;i++)
        {
            if(!visit[row][i]&&i!=col&&mat[row][i]>val)
            {
                num[mat[row][i]]={row,i};
            }
        }
        //列
        for(int i=0;i<m;i++)
        {
            if(!visit[i][col]&&i!=row&&mat[i][col]>val)
            {
                num[mat[i][col]]={i,col};
            }
        }
        minrow=num.size()?num.begin()->second[0]:-1;
        mincol=num.size()?num.begin()->second[1]:-1;
        minval=num.size()?num.begin()->first:-1;
        if(minrow!=-1&&mincol!=-1)
        {
            visit[minrow][mincol]=true;
            res++;
        }
        return {minrow,mincol,minval};
    }
    int maxIncreasingCells(vector<vector<int>>& mat) {
        int m=mat.size();
        int n=mat[0].size();
        int res=1; //基础为1
        //寻找最小点作为出发值
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                int minrow=i;
                int mincol=j;
                int minval=mat[i][j];
                int ans=1;
                vector<vector<bool>> visit(m,vector<bool>(n,false));
                //置访问标志
                visit[minrow][mincol]=true;
                while(minrow!=-1&&mincol!=-1)
                {
                    vector<int> temp;
                    temp = dfs(ans,mat,visit,m,n,minrow,mincol,minval);
                    minrow = temp[0];
                    mincol = temp[1];
                    minval = temp[2];
                }
                res=max(res,ans);
            }
        }
        return res;
    }
};

总结:有点难,但还好,继续加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/582348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何让Task在非线程池线程中执行?

Task承载的操作需要被调度才能被执行&#xff0c;由于.NET默认采用基于线程池的调度器&#xff0c;所以Task默认在线程池线程中执行。但是有的操作并不适合使用线程池&#xff0c;比如我们在一个ASP.NET Core应用中承载了一些需要长时间执行的后台操作&#xff0c;由于线程池被…

Linux:shell脚本的介绍,创建与执行

linux的shell脚本就是windows的bat脚本&#xff0c;也就是通常所说的批处理。更简洁地说&#xff0c;就是很多命令的结合体&#xff0c;就像编程一样。 windows脚本的扩展名是.bat&#xff0c;而linux脚本的扩展名则是.sh centos在编写shell脚本的文件最上边&#xff0c;需要加…

如何使用Sentinel的Slot插槽实现限流熔断,看完这篇文章会有新的收获

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇文章将详细介绍如何使用Sentinel的Slot插槽实现限流熔断&#xff0c;后续文章将详细介绍Sentinel的其他知识。 如果文章有什么需要改进的地方还请大佬不吝赐教&#x…

对于2023年参加国家计算机软考系统分析师的感想

文章目录 前言系分简介系分知识点今年的题型综合知识(上午选择题)案例分析&#xff08;下午简答分析题&#xff09;论文&#xff08;下午小作文&#xff09; 写在最后 前言 23年3月27日参加了国家计算机软考系统分析师&#xff0c;考完后很多的题库网站就有小道估分了。当然&a…

一些零零碎碎的记录

Questions1. 用户访问多网址服务器同一个IP是怎么回事 Q:用户访问服务器的同一个IP不同网址&#xff0c;服务器是如何区分的A: 在 HTTP 协议中&#xff0c;客户端通过发送请求报文来向服务器请求资源。每个 HTTP 请求都包含一个 HTTP 头部&#xff0c;其中包括了一些关键信息&…

力扣sql中等篇练习(三十)

力扣sql中等篇练习(三十) 1 即时食物配送||| 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below SELECT order_date,ROUND(100*count(IF(order_datecustomer_pref_delivery_date,customer_id,null))/count(*)…

studio one6免费版下载及配置要求 附精调效果包

提到编曲软件&#xff0c;就不得不说这款水果编曲软件。它对新手和老手都比较友好&#xff0c;是一款较为经典的编曲软件。 这款软件提供了强大而全面的音符、音效编辑器&#xff0c;可以在其中插入各种乐器声音&#xff0c;如果内置乐器无法满足编曲需求&#xff0c;还可以外…

ABAQUS计算随机振动设置及输出

ABAQUS计算随机振动设置及输出 1.分析步设置 随机振动主要包括两个分析步&#xff1a;频率和随机振动 1.1 频率设置 频率这里需要注意的是最高频率最好是扫频范围的2-2.5倍 比如随机频率区间是[0-2000hz],最高频率应该大于4000Hz&#xff0c;才能保证精度 1.2 随机响应设…

数据结构【栈】有哪些应用场景?

✨Blog&#xff1a;&#x1f970;不会敲代码的小张:)&#x1f970; &#x1f251;推荐专栏&#xff1a;C语言&#x1f92a;、Cpp&#x1f636;‍&#x1f32b;️、数据结构初阶&#x1f480; &#x1f4bd;座右铭&#xff1a;“記住&#xff0c;每一天都是一個新的開始&#x1…

如何在前端应用中合并多个 Excel 工作簿

本文由葡萄城技术团队于博客园原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 | 问题背景 ​ SpreadJS是纯前端的电子表格控件&#xff0c;可以轻松加载 Excel 工作簿中的数据…

Hack The Box - 关卡Dancing

SMB(全称是Server Message Block)是一个协议名&#xff0c;可用于在计算机间共享文件、打印机、串口等&#xff0c;电脑上的网上邻居就是靠它实现的。 SMB 是一种客户机/服务器、请求/响应协议。通过 SMB 协议&#xff0c;客户端应用程序可以在各种网络环境下读、写服务器上的…

干货|7种提高客户推荐率的方法,让你的客户成为你的推广大使!

大家都知道“客户推荐”是一种非常有效的业务推广方式。通过口碑传播&#xff0c;可以吸引更多的潜在客户&#xff0c;建立长期稳定的合作关系。 可以说&#xff0c;这种开发客户的方法:耗时少&#xff0c;成功率高&#xff0c;成本低&#xff0c;客户更好&#xff0c;堪称世界…

山西电力市场日前价格预测【2023-05-30】

日前价格预测 预测明日&#xff08;2023-05-30&#xff09;山西电力市场全天平均日前电价为350.71元/MWh。其中&#xff0c;最高日前价格为424.56元/MWh&#xff0c;预计出现在19: 30。最低日前电价为239.37元/MWh&#xff0c;预计出现在13: 00。 以上预测仅供学习参考&#xf…

律师使用ChatGPT 进行法律文献检索提交了错误信息;李开复表示,威力强大的大模型将彻底变革人工智能

&#x1f680; 一名律师使用ChatGPT 进行法律文献检索提交了错误信息 近日&#xff0c;一名律师在法庭案件中使用聊天机器人 ChatGPT 进行法律文献检索&#xff0c;结果提交了错误信息&#xff0c; 揭示了人工智能在法律领域的潜在风险&#xff0c;包括误传错误信息。 该事件…

数据分析师的基本职责(合集)

算法工程师的职责表述 算法工程师的职责表述1 职责 1、维护、扩展的大数据处理分析平台; 2、负责将先进的工业大数据分析技术转化为标准化的分析工具与模块; 3、规范并优化算法&#xff0c;提高可靠性; 4、帮助建立标准化的数据分析路线图&#xff0c;能够提取、转换并加强数据…

音视频技术开发周刊 | 295

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 微软炸通Windows与ChatGPT全家桶&#xff01;人手一个Copilot&#xff0c;AI宇宙降临 三位OpenAI掌舵人亲自撰文&#xff1a;我们应该如何治理超级智能&#xff1f; OpenA…

《Opencv3编程入门》学习笔记—第一章

《Opencv3编程入门》学习笔记 记录一下在学习《Opencv3编程入门》这本书时遇到的问题或重要的知识点。 第一章 邂逅opencv 参考推荐软件版本&#xff1a;visual studio2010 opencv2.4.9 visual studio安装教程: https://blog.csdn.net/qq_45768871/article/details/1081788…

LeetCode链表题(中等)剖析

文章目录 &#x1f490;文章导读&#x1f490;1.合并零之间的结点解题思路 &#x1f490;2.链表中最大孪生和解题思路 &#x1f490;3.链表的随机节点解题思路 &#x1f490;4.复杂链表的复制解题思路 &#x1f490;5.两辆交换两表中的节点解题思路 &#x1f490;文章导读 &…

【深圳触觉智能技术分享】RK3568 RK809电量计电池调试

本文基于IDO-SBC3568主板介绍说明PMIC RK809电量计的调试方法。 IDO-SBC3568-V1是一款基于RK3568的工控主板&#xff0c;采用22nm先进工艺制程&#xff0c;四核A55 CPU&#xff0c;主频高达2.0GHz&#xff0c;支持高达8GB高速LPDDR4&#xff0c;1T算力NPU &#xff0c;4K H.26…

如何在Allegro软件中快速复制走线和过孔?

在PCB设计过程中&#xff0c;快速而准确复制走线和过孔是提高设计效率和减少重复工作的关键所在&#xff0c;因此很多工程师会选择使用Allegro来复制走线和过孔&#xff0c;因为Allegro是一款功能强大且灵活的PCB设计软件&#xff0c;提供了多种工具和功能&#xff0c;自然包括…