CSDN话题挑战赛第2期
参赛话题:学习笔记
414.第三大的数 难度:简单
题目描述
给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
示例 1:
输入:[3, 2, 1] 输出:1 解释:第三大的数是 1 。
示例 2:
输入:[1, 2] 输出:2 解释:第三大的数不存在, 所以返回最大的数 2 。
示例 3:
输入:[2, 2, 3, 1] 输出:1 解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。 此例中存在两个值为 2
的数,它们都排第二。在所有不同数字中排第三大的数为 1 。
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:你能设计一个时间复杂度 O(n) 的解决方案吗?
解题思路
找出第几大的数,首先想到的就是先排序再找出相应的数。但是重复的怎么办呢?利用一个变量sum
记录前一个数不等于后一个数的个数,如果sum=2
,那么后一个数就是第三大的数。
代码演示
class Solution {
public:
int thirdMax(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end());
int sum=0;
for(int i=n-1;i>0;i--){
if(nums[i]!=nums[i-1]){
sum++;
if(sum==2)
return nums[i-1];
}
}
if(sum<2)
return nums[n-1];
//后面需要加return 0;不然if语句中如果不满足就没有返回值了
return 0;
}
};
598.范围求和Ⅱ 难度:简单
题目描述
给你一个 m x n
的矩阵 M ,初始化时所有的 0 和一个操作数组 op ,其中 ops[i] = [ai, bi]
意味着当所有的 0 <= x < ai
和0 <= y < bi
时, M[x][y] 应该加 1。
在 执行完所有操作后 ,计算并返回 矩阵中最大整数的个数 。
示例 1:
输入: m = 3, n = 3,ops = [[2,2],[3,3]] 输出: 4 解释: M 中最大的整数是 2, 而且 M
中有4个值为2的元素。因此返回 4。
示例 2:
输入: m = 3, n = 3, ops =
[[2,2],[3,3],[3,3],[3,3],[2,2],[3,3],[3,3],[3,3],[2,2],[3,3],[3,3],[3,3]]
输出: 4
示例 3:
输入: m = 3, n = 3, ops = [] 输出: 9
提示:
1 <= m, n <= 4 * 104
0 <= ops.length <= 104
ops[i].length == 2
1 <= ai <= m
1 <= bi <= n
解题思路
有点脑筋急转弯的意思,可以看到加上的结果是覆盖的,只要找到最小层叠的x
轴上的值和y
轴上的值即可。
二维数组中一维数组很多,如果你想每一个都加1那么就错了,只需要把二维数组第一列和第二列分别遍历一遍,找到最小的x
轴上的数和最小的y
轴上的数,最后相乘就是答案。
代码演示
class Solution {
public:
int maxCount(int m, int n, vector<vector<int>>& ops) {
int minx=m,miny=n;
for(int i=0;i<ops.size();i++){
//第一列
if(ops[i][0]<minx)
minx=ops[i][0];
//第二列
if(ops[i][1]<miny)
miny=ops[i][1];
}
return minx*miny;
}
};
419.甲板上的战舰 难度:中等
题目描述
给你一个大小为 m x n
的矩阵 board 表示甲板,其中,每个单元格可以是一艘战舰 'X'
或者是一个空位 '.'
,返回在甲板 board 上放置的 战舰 的数量。
战舰 只能水平或者垂直放置在 board 上。换句话说,战舰只能按 1 x k(1 行,k 列)
或 k x 1(k 行,1 列)
的形状建造,其中 k 可以是任意大小。两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰)。
示例 1:
输入:board = [[“X”,“.”,“.”,“X”],[“.”,“.”,“.”,“X”],[“.”,“.”,“.”,“X”]]
输出:2
示例 2:
输入:board = [[“.”]] 输出:0
提示:
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j] 是 ‘.’ 或 ‘X’
解题思路
这道题的题目其实有争议,可能翻译不准吧,应该理解为“战舰群”,而不是战舰,这样例子就好解释了,连在一起的算一个“战舰群”。
这题也有点“重复”的味道,连在一起的只有一个是计数的,那么这样只算一个呢?方法有很多,这里我用的方法是:
用res
记录“战舰群”总数,初始化为0,从“战舰群”的头部开始遍历,先让等于‘X’
的res++
,遍历到不是第一行或者第一列时,如果检测到头部有‘X’
,那么再res--
,因为前面已经计数了。
1.“战舰群”在一列:判断头部(i-1,j)
这个坐标,如果是‘X’
,那么res--
2.“战舰群”在一行:判断头部(i,j-1)
这个坐标,如果是‘X’
,那么res--
核心思想是从左上遍历到左下,重复的res--
代码演示
class Solution {
public:
int countBattleships(vector<vector<char>>& board) {
//行数,二维数组是数组的数组,长度就是多少行
int row=board.size();
int col=board[0].size();
int res=0;
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(board[i][j]=='X'){
res++;
if(i>0&&board[i-1][j]=='X')
res--;
if(j>0&&board[i][j-1]=='X')
res--;
}
}
}
return res;
}
};