CSDN话题挑战赛第2期 参赛话题:学习笔记
文章目录
453.最小操作次数使数组元素相等? ?难度:中等
题目描述
解题思路
代码演示
283.移动零? ?难度:简单
题目描述
解题思路
代码演示
118.杨辉三角? ?难度:简单
题目描述
解题思路
代码演示
453.最小操作次数使数组元素相等? ?难度:中等
题目描述
给你一个长度为 n 的整数数组,每次操作将会使 n - 1 个元素增加 1 。返回让数组所有元素相等的最小操作次数。
示例 1:
输入:nums = [1,2,3] 输出:3 解释: 只需要3次操作(注意每次操作会增加两个元素的值): [1,2,3] ?=> ?[2,3,3] ?=> ?[3,4,3] ?=> ?[4,4,4]
示例 2:
输入:nums = [1,1,1] 输出:0
提示:
n == nums.length 1 <= nums.length <= 105 -109 <= nums[i] <= 109 答案保证符合 32-bit 整数
解题思路
思路:逆向思维,n-1个数加1等价于1个数减1,只需要计算将数组中所有元素都减少到数组中元素最小值所需的操作数即可。 本来我的思路是让最大的数减1,然后再找出最大的数减1,循环到全部相等下去即可得到答案,可是超时了,也有可能我写的错了,最后只能看答案了。。只能说我的思路只对了一半哈哈哈。
代码演示
?官方答案:
class Solution {
public:
int minMoves(vector<int>& nums) {
int minNum = *min_element(nums.begin(),nums.end());
int res = 0;
for (int num : nums) {
res += num - minNum;
}
return res;
}
};
翻译过来就是:
class Solution {
public:
int minMoves(vector<int>& nums) {
sort(nums.begin(),nums.end());
int minNum=nums[0];
int res = 0;
for (int i=0;i<nums.size();i++){
int num=nums[i];
res+=num-minNum;
}
return res;
}
};
283.移动零? ?难度:简单
题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意?,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12] 输出: [1,3,12,0,0]
示例 2:
输入: nums = [0] 输出: [0]
提示:
1 <= nums.length <= 104 -231?<= nums[i] <= 231?- 1
进阶:你能尽量减少完成的操作次数吗?
解题思路
方法1:两次遍历 定义一个索引j=0,遍历数组,让不等于0的数赋值到j位置上的数组上,j++,即不等于0的数放到前面,后面再来一次从j开始的遍历,让后面的数等于0。 方法2:双指针法 定义两个索引(指针)left和right初始化为0,left先不动,right从左往右移动,遇上非0元素,交换left和right对应的元素,交换之后left++。
代码演示
方法1:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int j=0;
for(int i=0;i<nums.size();i++){
if(nums[i]!=0)
nums[j++]=nums[i];
}
for(int i=j;i<nums.size();i++){
nums[i]=0;
}
}
};
方法2:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int left=0,right=0;
while(right<nums.size()){
if(nums[right]!=0){
swap(nums[left],nums[right]);
left++;
}
right++;
}
}
};
118.杨辉三角? ?难度:简单
题目描述
给定一个非负整数?numRows,生成「杨辉三角」的前?numRows?行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: numRows = 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
示例?2:
输入: numRows = 1 输出: [[1]]
提示:
1 <= numRows <= 30
解题思路
思路:把杨辉三角用二维数组存放,两次遍历
可以发现二维数组第一列和对角线都是1,那么就初始化为1。外遍历:因为初始化是从第一行开始初始化,而第一行只有一个数,初始化需要体现出对角线,那么需要resize()函数改变vector容器的大小添加一行再初始化。内遍历:前一行两个数相加。
代码演示
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>>res(numRows);
for(int i=0;i<numRows;i++){
res[i].resize(i+1);
res[i][0]=res[i][i]=1;
for(int j=1;j<i;j++){
res[i][j]=res[i-1][j-1]+res[i-1][j];
}
}
return res;
}
};
|