1.合并两个有序数组
这道题标签是数组,双指针。最朴素的解法当然是先合并再排序,但这样做的时间复杂度为O((n+m)log(n+m))。
1)合并后排序,这里也贴一下这种做法的代码吧(包含测试代码),但这种方法没有利用数组本身有序的特点。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
for(int i=0;i<n;i++){
nums1[i+m]=nums2[i];
}
sort(nums1.begin(),nums1.end());
}
};
void print(vector<int>& nums){
for(int i=0;i<nums.size();i++)
cout<<nums[i]<<" ";
cout<<endl;
}
int main()
{
Solution s;int a;
vector<int> nums1={1,2,3,0,0,0};
vector<int> nums2={2,5,6};
s.merge(nums1,3,nums2,3);
print(nums1);
return 0;
}
2)双指针,从前往后。写这段程序的时候,在复制数组的时候碰到一个错误,Line 923: Char 34: runtime error: reference binding to null pointer of type 'value_type' (stl_vector.h),只好改为了全部复制,这个问题后面再看看是为什么。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
vector<int> nums1_copy=nums1;
//for(int k=0;k<m;k++){
//nums1_copy[k]=nums1[k];
//}
nums1.clear();
int i=0,j=0;
while(i<m&&j<n){
if(nums1_copy[i]<nums2[j]){
nums1.push_back(nums1_copy[i]);
i++;
}
else{
nums1.push_back(nums2[j]);
j++;
}
}
if(i==m){
for(;j<n;j++)
nums1.push_back(nums2[j]);
}
if(j==n){
for(;i<m;i++)
nums1.push_back(nums1_copy[i]);
}
}
};
3)双指针,从后往前,这个写了有一会儿,发现通过调试一些测试用例能比较快的找到bug所在。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(m==0) nums1=nums2;
int i=m-1,j=n-1,p=m+n-1;//p用来追踪添加元素的位置
while(j>=0&&i>=0){
if(nums1[i]<=nums2[j]){
nums1[p]=nums2[j];
j--;
}
else{
nums1[p]=nums1[i];
i--;
}
p--;
}
if(i==-1){
while(j>=0){
nums1[p]=nums2[j];
j--;
p--;
}
}
}
};
2.有序数组的平方
这道题目是上一道题目的相似题目,标签也是数组和双指针。一旦想明白非负数部分和负数部分都是有序的后就可以参考上一道题目的解法。使用双指针的技巧合并这两个数组。题目的提示已经明确了数组长度的范围,以及元素的范围,不需要处理空数组的情况和平方后可能溢出的情况。怎么找到负数和非负数分界的地方?注意到之前写的一些if是不必要的,可以直接放到循环的条件里。
vector<int> res;
int j=0;
int n=A.size();
//if(n==1) {res[0]=A[0]*A[0];return res;}
while(j<n&&A[j]<0)
j++;//j记录的是第一个不小于0的数的下标
int i=j-1;
while(i>=0&&j<n){
if(A[i]*A[i]<A[j]*A[j]){
res.push_back(A[i]*A[i]);
i--;
}
else{
res.push_back(A[j]*A[j]);
j++;
}
}
while(j<n){
res.push_back(A[j]*A[j]);
j++;
}
while(i>=0){
res.push_back(A[i]*A[i]);
i--;
}
return res;
3.买卖股票的最佳时机
这道题目自己试着先写了没有通过,找到最低历史价格然后在它的右边找到最大的一个数这个方法是有问题的。还是应该先把算法想清楚再开始写,下面这个是官方题解的方法二:求出每个卖出时机的最大差值,取其中最大的一个。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int minprice=2147483647;
int maxprofit=0;
for(int i=0;i<prices.size();i++){
if(prices[i]<minprice){
minprice=prices[i];
}
else if((prices[i]-minprice)>maxprofit){
maxprofit=prices[i]-minprice;
}
}
return maxprofit;
}
};