第一题 颜色分类
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
class Solution {
public:
void sortColors(vector<int>& nums) {
int k=nums.size();
for(int i=0,j=0,m=k-1;m>=i;i++){ //要用>= 注意判断条件是m>=i
if(nums[i]==2){
nums[i]=nums[m];
nums[m]=2;
m--;
i--;
}
else if(nums[i]==0){
nums[i]=nums[j];
nums[j]=0;
j++;
}
}
}
};
这道题比较简单,自己直接写了,需要注意的点就是for的判断语句是m>=i,画图就懂了,运行的时候有个小错误,就是我把>=写成了=>,现在知道了没有=>的写法。
第二题 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
这道题我我刚进力扣的时候就写了,用的sort 函数,现在再写,如果不用sort有点不会写,用冒泡算法的话说我超时了,毕竟时间复杂度只能是O(n),看了答案有很多种,有一种空间换时间,设置一个很大的数组存放的,感觉不太好但又不能说错,别人用的二路快排和堆排序,但自己对这块知识掌握不熟练,答案也没心思细看,就先跳过了,后面再学数据结构的时候再回来解决吧。
第三题 合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
这个题刚开始的时候想着不能创建新的数组然后就不会写,看了答案有好几个都是创建新的数组,之后看见一个用三指针从后面往前排序的,看懂图画之后自己把代码写了出来
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
for(int i=n-1,j=m-1,k=m+n-1;k!=-1;){ //i是nums2的位置,i=-1表示nums2为空,直接输出
if(i==-1){ //j是nums1的位置 k是正确答案位置,k从nums1的总长开始
return;
}
if(j==-1){ //当j(nums1)为-1(空)时 若i(nums2)不为-1(空)
for(int t=i;t!=-1;t--){ //则nums2剩下的元素都比nums1小,都能放到后面
nums1[t]=nums2[t];
}
return;
}
if(nums2[i]>nums1[j]){
nums1[k]=nums2[i];
k--;
i--;
continue; //continue; 表示下面不用走了,执行for下一个循环
}
else if(nums1[j]>=nums2[i]){
nums1[k]=nums1[j];
k--;
j--;
}
}
}
};
自己写代码其间出了很多bug,首先是没注意看m是nums1的元素长,我还以为是总长,后来判断的时候会出现nums2空了或者nums1的指针指向-1的位置越界了,这些错误,所以要在前面写两个if判断避免这些情况,从后往前插入的方法好处是不用考虑插入的元素因为位置的问题把没插入的元素覆盖掉,因为我画图发现它是覆盖不了的,所以就用这个方法,把bug改好之后还是很满意的。