寒假刷题计划(第1天)
时间:2022.01.05
题数:05
题目类型:数组
1.删除排序数组中的重复项
第一种方法:快慢指针(c++)
public:
int removeDuplicates(vector<int>& nums) {
int length=nums.size();
if(length==0) return 0;
int fast=1,slow=1;
while(fast<length){
if(nums[fast]!=nums[fast-1]){//不重复的时候慢指针向前移动
nums[slow]=nums[fast];//并且将快指针移到慢指针的位置
++slow;
}
++fast;
}
return slow;//慢指针的位置就是没有重复元素的位置
};
2.买卖股票的最佳时机 II
第一种方法:贪心(c++)
public:
int maxProfit(vector<int>& prices) {
int nums=0;
int length=prices.size();
if(length<=1) return 0;
for(int i=0;i<length-1;i++){
if(prices[i]<prices[i+1]){//但第二天卖出就可以产生利息
nums+=(prices[i+1]-prices[i]);//将所有可以赚的差价全部算上
}
}
return nums;
}
};
第二种方法:动态规划(c++&官方解法)
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int dp0 = 0, dp1 = -prices[0];
for (int i = 1; i < n; ++i) {
int newDp0 = max(dp0, dp1 + prices[i]);
int newDp1 = max(dp1, dp0 - prices[i]);
dp0 = newDp0;
dp1 = newDp1;
}
return dp0;
}
};
3.旋转数组
第一种方法:分治(c++)
public:
void reverse(vector<int>& nums, int start, int end) {//反转函数,头尾向中间翻转
while (start < end) {
swap(nums[start], nums[end]);
start += 1;
end -= 1;
}
}
void rotate(vector<int>& nums, int k) {
k %= nums.size();
reverse(nums, 0, nums.size() - 1);//全部翻转
reverse(nums, 0, k - 1);//翻转前k个
reverse(nums, k, nums.size() - 1);//翻转后面的数组
}
};
4. 存在重复元素
第一种方法:排序后判断
public:
bool containsDuplicate(vector<int>& nums) {
sort(nums.begin(), nums.end());//排序
for (int i = 1; i < nums.size(); i++) {//排序后的数组如果前后存在相同则有重复元素
if (nums[i] == nums[i - 1]) {
return true;
}
}
return false;
}
};
第二种方法:散列||哈希
public:
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> s;
for (int x: nums) {
if (s.find(x) != s.end()) {
return true;
}
s.insert(x);
}
return false;
}
};
总结
均为入门题,不足挂齿