二分法
数组
-
Leetcode 605: Can Place Flowers
easy
- 解题关键
-
corner case处理
if (n == 0) { return true; } int length = flowerbed.length; if (length == 1) { return flowerbed[0] == 0; }
-
找到符合条件数组中0的位置
if (i == 0) { // handle the start if (flowerbed[i + 1] == 0) { ret ++; flowerbed[0] = 1; } // handle the end } else if (i == length - 1) { if (flowerbed[length - 2] == 0) { ret ++; flowerbed[length - 1] = 1; } } else if (flowerbed[i - 1] == 0 && flowerbed[i + 1] == 0) { ret ++; flowerbed[i] = 1; }
-
- 解题关键
-
Leetcode 189: Rotate Array
medium
- 解题关键
-
1,corner case 判断
-
当数组长度=0或=1,直接返回
int length = nums.length; if (length == 0 || length == 1) { return nums; }
-
2,若k大于或等于数组长度的情况,实际代表旋转后又重新回到初始状态,因此需要对k取模,只排序取模后的长度
k %= length
-
-
2,交换索引位置的区间元素
-
1,交换方法
private void swap(int[] nums, int left, int right) { int tmp; while (left < right) { tmp = nums[left]; nums[left] = nums[right]; nums[right] = tmp; left ++; right --; } }
-
2,注意交换的索引位置
swap(nums, 0, length - 1); // 先旋转整个数组 swap(nums, 0, k - 1); // 再旋转从0到k - 1处的元素 swap(nums, k, length - 1); // 再旋转从k到length - 1处的元素 /** [1,2,3,4,5,6,7] k = 3 第一次交换:[7,6,5,4,3,2,1] 第二次交换:[5,6,7,4,3,2,1] 第三次交换:[5,6,7,1,2,3,4] **/
-
-
- 解题关键
-
Leetcode 229: Majority Element II
medium
- 解题关键
- 1,暴力解法:创建一个Map存储数组中所有元素和出现的次数,遍历Map,将大于
n / 3
的元素组合成List
然后返回 - 2,Boyer–Moore majority vote algorithm
- 1,暴力解法:创建一个Map存储数组中所有元素和出现的次数,遍历Map,将大于
- 解题关键
贪心算法(Greedy Algorithm)
-
Leetcode 122: Best Time to Buy and Sell Stock II
easy
- 解题关键:
-
1, corner case 判断
// 若数组长度小于2,那么无论是sell或者是buy,都不会有收益 if (prices.length < 2) { return 0; }
-
2, 计算每一次sell和buy过程获得的收益进行叠加,从而得到最大收益
// 索引从1开始,便于与i - 1进行比较 for (int i = 1; i < prices.length; i ++) { // 只有当前值大于前一天的值,说明sell才会获得收益 if (prices[i] > prices[i - 1]) { ret += prices[i] - prices[i - 1] } }
-
- 解题关键:
-
Leetcode 455: Assign Cookies
easy
- 解题关键:
-
1, corner case 判断
// 若s长度为0,则满足不了任何孩子,因此可直接返回0 if (s.length == 0) return 0; // 但由于我们使用贪心算法,遍历两个数组时,需要索引条件同时成立,因此也可不做此判断
-
2, 考虑到孩子的贪心度是第i个孩子为g[i],因此可以对两个数组先进行排序
Arrays.sort(g); Arrays.sort(s);
-
3, 同时遍历两个数组,当g[i]小于或等于s[j]时,说明可以满足当前孩子,则叠加返回值,需要注意的是索引j为s的最小值,若该值满足当前孩子,说明后面的同样满足,因此只有在g[i]大于s[j]时,才将j进行叠加
while (i < g.length && j < s.length) { if (g[i] <= s[j]) { ret ++; i ++; } j ++; }
-
- 解题关键:
-
Leetcode 921: Minimum Add to Make Parentheses Valid
medium
- 解题关键:
-
1,corner case判断
// 考虑到字符串有可能为空,因此当字符串为空时直接返回0 if (s.length() == 0) return 0;
-
2,遍历字符串,定义open(’(’)计数,初始化为0,计数逻辑为:
- 当字符为’('时,open加1
- 当字符为’)'时
-
先判断open是否为0,若为0,说明前面的’(‘与’)'已经抵消,因此需要增加补充的数量(ret)加1
-
若open不为0,那么优先与open抵消,即open减1
for (int i = 0; i < s.length(); i ++) { if (s.charAt(i) == '(') { open ++; } else { if (open == 0) { ret ++; } else { open --; } } }
-
-
3,最后返回值为open+ret总数
return ret + open;
-
- 解题关键:
-
Leetcode 714: Best Time to Buy and Sell Stock with Transaction Fee
medium
- 解题关键:
-
1,corner case判断
// 当数组长度小于2时,此时没有任何收益,直接返回0 if (length < 2) return 0;
-
2,定义需要的一些变量
int[] dp = new int[length]; // 存储遍历数组时所有可能的收益 int maxProfit = 0; // 初始化最大收益 int prevProfit = 0; // 初始化遍历数组时当前索引之前的收益 int minPrice = prices[0]; // 初始化最小价格为当前数组第一个值
-
3,遍历数组
for (int i = 1; i < length; i ++) { dp[i] = prices[i] - minPrice - fee + prevProfit; // 每次遍历取得的收益存进dp数组 if (prevProfit - minPrice < maxProfit - prices[i]) { // 若之前的收益减去当前最小价格小于最大收益减去当前价格,说明之前的收益不是最大化的 prevProfit = maxProfit; // 更新之前的收益为最大收益 minPrice = prices[i]; // 更新最小价格为当前价格 } maxProfit = Math.max(maxProfit, dp[i]); // 更新最大收益 }
-
- 解题关键:
-
Leetcode 435: Non-overlapping Intervals
medium
- 解题关键:
-
1,corner case判断
// 若二维数组长度为1,说明只有一个区间,因此没有任何可以去掉的多余区间,直接返回0 if (length < 2) return 0;
-
2,由于是去掉会重叠的区间,最后得到不重叠的区间,因此需要考虑区间的判断逻辑
- 当intervals[i][0]大于等于intervals[i - 1][1]时,两个区间可认为不重叠
-
// 先将二维数组进行排序,以子数组中第一个元素大小为基准 Arrays.sort(intervals, (a, b) -> a[0] - b[0]); // 定义一个缓存数组,存储当前区间范围,便于二维数组时子数组的区间判断 int[] tmp = new int[2]; tmp[0] = Integer.MIN_VALUE; tmp[1] = Integer.MIN_VALUE; // 遍历二维数组 for (int i = 0; i < intervals.length; i ++) { // 当前区间范围为tmp,因此如果tmp[1]大于intervals[i][0]时,说明会有重叠,需要去掉 if (tmp[1] > intervals[i][0]) { ret ++; // 考虑到不重叠的情况,当前区间的end应该取较小值 tmp[1] = Math.min(tmp[1], intervals[i][1]); } else { // 若tmp[1]小于等于intervals[i][0],说明两个区间不重叠,由于数组已经经过排序,因此当前区间变为intervals[i],继续进行比较 tmp = intervals[i]; } }
- 解题关键: