题目链接
思路:本题中第i天有五种状态:不操作、第一次持有、第一次不持有、第二次持有、第二次不持有。
注意可以同一天进行买卖,而且是多次买卖。
class Solution {
public:
int maxProfit(vector& prices) {
int len=prices.size();
vector> dp(len,vector(5));
dp[0][0]=0;
dp[0][1]=-prices[0];
dp[0][2]=0;
dp[0][3]=-prices[0];
dp[0][4]=0;
for(int i=1;i
题目链接
本题和上一题不同的就是,第i天可以有2*k+1种状态,需要额外用一个变量j记录第i天第j次买卖。
至于边界条件,可以代入k=2,进行验证。
class Solution {
public:
int maxProfit(int k, vector& prices) {
int len=prices.size();
if(len==0) return 0;
vector> dp(len,vector(2*k+1,0));
for(int i=1;i<2*k;i+=2){
dp[0][i]=-prices[0];//第0天持有一定是买入//错因:是prices[0],不是prices[i]
}
for(int i=1;i
题目链接
思路:快排的思路。只要left和right不指向同一个元素,如果left指向的元素一直是奇数,就一直往后移动left指针,如果right指向的元素一直是偶数,就一直往前移动right指针,然后两个指针停止的位置肯定是left指向偶数,right指向奇数,那么将这两个元素进行交换即可,然后再开始下一轮。
class Solution {
public:
vector exchange(vector& nums) {
int left=0,right=nums.size()-1;
while(left
题目链接
思路:一说是在排序数组中查找元素,自然就是二分查找。
class Solution {
public:
vector twoSum(vector& nums, int target) {
for(int i=0;i{nums[i],fin};
else if(nums[mid]{};
}
};
题目链接
思路:双指针法,快指针用于获取我们想要的元素,满指针指向我们获取的新元素更新在哪里。先去除字符串中多余的空格,然后整体反转+局部反转。其实相当于同时操作新数组和旧数组,外层循环是快指针用于遍历旧数组,然后用满指针更新新数组。
class Solution {
public:
void reverse(string&s,int start,int end){
for(int i=start,j=end;i
错因:1、更新完新数组之后忘记改字符串的大小了,因为我们是在原数组上直接进行更新的,所以要改变新数组的大小。
2、在反转单词的时候for循环的边界条件写错了,应该有等于,因为此时for循环里的下标i是为了我们记录单词的末尾位置,但是小标i指向的是单词的末尾位置的后一个位置,所以要有等于s.size()。
题目链接
思路:回溯法。注意同一个格子的元素不能重复访问,所以将它改成一个#(因为board
和word
仅由大小写英文字母组成,所以#一定不会被访问),然后回溯的时候再改回去即可。当然也可以用visited数组记录访问情况,但是这样的空间复杂度比较高。
class Solution {
public:
bool dfs(vector>& board, string word,int k,int i,int j){
int m=board.size();
int n=board[0].size();
if(!(i>=0&&i=0&&j>& board, string word) {
for(int i=0;i
错因:dfs的递归终止条件中的边界条件写错,写成了i<=m和j<=n,应该是<。
本题因为单词内字符是有顺序的,所以可能前面的字符不符合,但是后面的字符符合了,所以必须要进行回溯。
题目链接
本题和上一题不一样的是,如果遍历到一个格子是不符合条件的,那它一定就是不符合了,所以不用进行回溯。
class Solution {
public:
int getval(int i,int j){//直接求出两个数的数位之和
int res=0;
while(i){
res+=i%10;
i/=10;
}
while(j){
res+=j%10;
j/=10;
}
return res;
}
int dfs(int i, int j, int k,int m,int n,vector>& visited){
if(i>=m||j>=n||getval(i,j)>k||visited[i][j]==true) return 0;//visited[i][j]==true说明该点已经被之前某条路径访问过了,已经计算过了,如果再沿着这个位置往右往下走的话,必然会走重复的路径//就相当于设了个障碍,不能再继续往后搜索了,该点也不能计算,所以返回0
visited[i][j]=true;
return 1+dfs(i+1,j,k,m,n,visited)+dfs(i,j+1,k,m,n,visited);
}
int movingCount(int m, int n, int k) {
vector> visited(m,vector(n,false));
return dfs(0,0,k,m,n,visited);
}
};
注意数位求和的过程。
开始很纠结为什么dfs函数里,visited[i][j]==true,要返回0。因为visited[i][j]==true说明该点已经被之前某条路径经过了,也就是已经计算过了,如果是true就返回0,也就是当前路径经过该点的后面的路径不要再进行搜索了,而且该点也不能进行计算,所以直接返回0。
本题用unordered_set的写法还是不太会,有待继续研究。