1、Leetcode-面试经典150题目6-189. 轮转数组
思路
1、要实现题目中的循环轮转数组,一个关键的公式是:(i+k)%n ,可以实现循环取数。
2、首先,第一种方法解释开辟一个额外的数组,将原来下标i的元素放到新数组下标为(i + k)mod n的位置,即轮转之后的数组。
3、nums.assign(temp.begin(),temp.end());将temp数组拷贝到nums中
//方法1 使用额外数组
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
vector<int> newArr(n);
for(int i = 0;i < n;++ i)
newArr[(i+k)%n] = nums[i];
//将newarr数组拷贝到原数组
nums.assign(newArr.begin(),newArr.end());
}
};
还有另外一种方法,就是利用数组翻转,举个例子
[1,2,3,4,5,6,7] k = 3 ------> 我们的目标 [5,6,7, 1,2,3,4]
1.第一次翻转:整个翻转 [7,6,5,4,3,2,1]
2.第二次翻转:将前面翻转过来的即前k个翻转, [5,6,7,4,3,2,1]
3.第三次翻转:将从第k+1到结尾翻转[5,6,7,1,2,3,4]
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k %=nums.size(); //对于数组长度小于k的情况要考虑
reverse(nums.begin(),nums.end());
reverse(nums.begin(),nums.begin()+k);
reverse(nums.begin()+k,nums.end());
}
};
知识点总结: 数学、数组、双指针
2、Leetcode-面试经典150题目7-121. 买卖股票的最佳时机
思考
1.一开始直接暴力,过了200个样例,但是后面时间超时了
const int N = 100010;
class Solution {
public:
int maxProfit(vector<int>& prices) {
int max = 0, cnt; // 最大利润
for (int i = 0; i < prices.size(); i++) {
for (int j = i + 1; j < prices.size();
j++) // 卖出时间必须大于买入时间
{ if(prices[j] <= prices[i] || prices[j-1] >= prices[j]){
continue;
}else{
cnt = prices[j] - prices[i];
if (cnt > max)
max = cnt;
}
}
}
return max;
}
};
2.暴力法超时,时间复杂度O(n^2),所以必须要转换为一维的
3.用动态规划的思想,dp[i]为第i天以前的最低价,所以第i天的最大利润就是price[i]-dp[i]
class Solution {
public:
int maxProfit(vector<int>& prices) {
int dp[prices.size()];
int ans = 0;
dp[0] = prices[0];
for(int i = 1; i < prices.size();i++){
dp[i] = min(dp[i-1],prices[i]);
ans = max(ans,prices[i]-dp[i]);
}
return ans;
}
};
知识点总结:数组、动态规划
3、Leetcode-面试经典150题目8-122. 买卖股票的最佳时机 II
思路:
1.状态方程如下表示,对于dp[i,0] ,可能前一天有一支股票或者前一天也没有股票。对于dp[i,1],可能前一天依然就一支股票或者前一天没有今天买入的。
2.状态规划类的问题最难想的就是状态转移方程,需要仔细思考状态是如何转移的。
3.对于本题和上题的区别,上题只用买入卖出一次,状态只有一维,只用考虑在第i天之前买入时最低价。对于本题,因为每天交易之后只可能存在手里有一支股票或者没有股票的状态,所以每天都必须要考虑有股票和没股票的状态。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int dp[n][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
if (n == 1)
return 0;
for (int i = 1; i < n; i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[n - 1][0];
}
};
知识点总结:数组、动态规划、贪心
每日一言:无论你的人生路途有多么曲折,都要保持一颗坚韧不拔的心,因为终点的就在前方。
2024年3月21日
softdream