携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情 >>
每日三刷,剑指千题
计划简介:
- 每日三题,以中等题为主,简单题为辅进行搭配。保证质量题1道,数量题3道。
- 每日早通勤在LeetCode手机端选题,思考思路,没答案的直接看题解。
- 每日中午进行编码,时间控制在一小时之内。
- 下班前半小时进行整理总结,并发布到掘金每日更文活动。
说明:
- 基于以前的刷题基础,本次计划以中等题为主,大部分中等题都可以拆分为多个简单题,所以数量保证3,质量保证一道中等题即可。
- 刷题顺序按照先刷链表、二叉树、栈、堆、队列等基本数据结构,再刷递归、二分法、排序、双指针等基础算法,最后是动态规划、贪心、回溯、搜索等复杂算法。
- 刷题过程中整理相似题型,刷题模板。
- 目前进度 178/1000 。
今日题型
贪心算法:只考虑当前最优解。
[122]买卖股票的最佳时机 II
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。
解析
典型贪心
Code
class Solution {
public int maxProfit(int[] prices) {
// 贪心算法 在每一步总是做出在当前看来最好的选择。
// 对于 「今天的股价 - 昨天的股价」,得到的结果有 3 种可能:
// ① 正数,② 0,③负数。贪心算法的决策是: 只加正数 。
if (prices.length < 2){
return 0;
}
int ans = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i]- prices[i-1]>0){
ans += prices[i]- prices[i-1];
}
}
return ans;
}
}
[397]整数替换
给定一个正整数 n ,你可以做如下操作:
- 如果
n是偶数,则用n / 2替换n。 - 如果
n是奇数,则可以用n + 1或n - 1替换n。
返回 n 变为 1 所需的 最小替换次数 。
示例 1:
输入:n = 8
输出:3
解释:8 -> 4 -> 2 -> 1
示例 2:
输入:n = 7
输出:4
解释:7 -> 8 -> 4 -> 2 -> 1
或 7 -> 6 -> 3 -> 2 -> 1
解析
奇数时加1还是减1需要根据二进制前一位是0还是1判断。
Code
class Solution {
public int integerReplacement(int _n) {
long n = _n;
int ans = 0;
while (n != 1) {
if (n % 2 == 0) {
n /= 2;
} else {
if (n != 3 && (n + 1) / 2 % 2 == 0) n++;
else n--;
}
ans++;
}
return ans;
}
}
[402]移掉 K 位数字
给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
示例 1 :
输入:num = "1432219", k = 3
输出:"1219"
解释:移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219 。
解析
如果当前数字比前面的小,则移除高位且大的数字,让后面小的移到高位。
最后截取需要的位数,并且去掉最高位的 0 。
Code
class Solution {
public String removeKdigits(String num, int k) {
// 不能简单的移除 0 或者 最高位
// 如果每次都按最优的决策?即 k=1时怎么做最优?
// 如果当前遍历的数比栈顶大,符合递增,是满意的,让它入栈。
// 如果当前遍历的数比栈顶小,栈顶立刻出栈
int remain = num.length() - k;
Stack<Character> stack = new Stack<>();
stack.push(num.charAt(0));
for (int i = 1; i < num.length(); i++) {
while (k > 0 && !stack.isEmpty() && num.charAt(i) < stack.peek()) {
stack.pop();
k--;
}
stack.push(num.charAt(i));
}
StringBuilder ans = new StringBuilder();
while (!stack.isEmpty()) {
ans.append(stack.pop());
}
String s = ans.reverse().substring(0, remain);
while (s.startsWith("0")) {
s = s.substring(1);
}
if (s.equals("")) {
s = "0";
}
return s;
}
}
\