题目1:738.单调递增的数字
要想找一个单调递增且不大于n的最大数字,那么高位就尽量不变,然后找不满足单调递增的位置,将这个位置减一,后面的低位置为9。
这一题代码虽然不难,但是要真正理解,还是要多举例一些数字。
从前往后遍历:
从前往后遍历各位数字,找到第一个开始下降的数字[i],即某个数字的后面数字大于这个数的下标(如1234321种的4);
将[i]-1,然后将[i+1],各位数字设置为9(将1234321种的4减一,然后将[i+1]之后的数字置为9,即为1233999)。
class Solution {
public:
int monotoneIncreasingDigits(int n) {
if (n < 10) return n;
string num = to_string(n);
//从前往后遍历数字,找第一个开始下降的数字的下标
int i = 1;
while (i < num.size() && num[i - 1] <= num[i]) i++;
if (i < num.size()) { //有不符合要求的数字
while (i > 0 && num[i - 1] > num[i]) { //前边的数字大于后边的数字
num[i - 1] --; //将前边的数字减一
i --;
}
for (i += 1; i < num.size(); i++) { //将i+1后的数字全部置为9
num[i] = '9';
}
}
return stoi(num);
}
};
还有一种方法是从后往前遍历:
class Solution {
public:
int monotoneIncreasingDigits1(int n) {
string num = to_string(n);
int flag = num.size(); //flag标记赋值9从哪里开始,设置默认值为了防止第二个for循环在flag没有被赋值的情况下执行
//从后往前遍历,i从最后一位数字开始,找符合单调递增的数字
for (int i = num.size() - 1; i > 0; i--) {
if (num[i - 1] > num[i]) { //如果前一位数字大于后一位数字,即不符合单调递增
flag = i; //后一位数字置为9
num[i - 1]--; //前一位数字减一
}
}
for (int i = flag; i < num.size(); i++) { //将符合单挑递增后的数字都置为9
num[i] = '9';
}
return stoi(num);
}
};
题目2:714. 买卖股票的最佳时机含手续费
之前做了一道买卖股票的最佳时机Ⅱ,和这一题的差别就是少了手续费
如果带上手续费,
如果当前卖出的价格大于买入的价格加手续费就能卖,但是,只是能卖,这里记录下,等到最高点再卖;
如果当前卖出的价格小于买入的价格加手续费,那肯定再等等了
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int result = 0;
int minprice = prices[0]; //记录最低价格
for (int i = 0; i < prices.size(); i++) {
if (prices[i] < minprice) minprice = prices[i]; //买入股票
if (prices[i] >= minprice && prices[i] <= minprice + fee) continue; //不买不卖,也不需要计算利润,因为没有
if (prices[i] > minprice + fee) { //计算利润,但是并不一定真的卖出,所以要重新计算买入价格
result += prices[i] - minprice - fee;
minprice = prices[i] - fee;
}
}
return result;
}
};
题目3:968.监控二叉树
有空再写