力扣hot100做题整理71-80
文章目录
- 1.柱状图中的最大矩形
- 2.数组中的第k个最大元素
- 3.前k个高频元素(**)
- 4.买卖股票的最佳时机
- 5.跳跃游戏(*)
- 6.跳跃游戏2(*)
- 7.划分字母区间(*)
- 8.爬楼梯
- 9.杨辉三角(*)
- 10.打家劫舍
1.柱状图中的最大矩形
找右边第一个比他小的元素(单调递减栈)
注意控制左右边界,避免判断(如果存在递增的一组元素就不会无结果)
class Solution {public int largestRectangleArea(int[] heights) {// 1.加边界int[] newHeights = new int[heights.length+2];for (int i = 0; i < heights.length; i++) {newHeights[i+1] = heights[i];}// 单调递减栈Stack<Integer> stack = new Stack<>();int res = 0;for (int i = 0; i < newHeights.length; i++) {while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) {// 当前高度int h = newHeights[stack.pop()];int left = stack.peek();int right = i;res = Math.max(res, h * (right-left-1));}stack.push(i);}return res;}
}
2.数组中的第k个最大元素
求第k个最大元素用小顶堆
PriorityQueue min_Heap = new PriorityQueue<>();
min_heap.size()求长度
min_heap.poll()弹出根元素
min_heap-offer(nums[i])加入元素
class Solution {public int findKthLargest(int[] nums, int k) {PriorityQueue<Integer> min_Heap = new PriorityQueue<>();for (int i = 0; i < nums.length; i++) { // 小顶堆存放if (min_Heap.size() < k) {min_Heap.offer(nums[i]);} else {if (nums[i] > min_Heap.peek()) {min_Heap.poll();min_Heap.offer(nums[i]);}}}return min_Heap.peek();}
}
3.前k个高频元素(**)
理解如何遍历hashmap
for (Map.Entry<Integer, Integer> entry: map.entrySet())
获取key和value
map.getKey()
map.getValue()
如果只遍历key (map.keySet())
如果只遍历value(map.values))
class Solution {public int[] topKFrequent(int[] nums, int k) {// 1. 统计每个元素出现的次数HashMap<Integer, Integer> map = new HashMap<>();for (int num : nums) {map.put(num, map.getOrDefault(num, 0) + 1);}PriorityQueue<Map.Entry<Integer, Integer>> min_heap = new PriorityQueue<>((a, b) -> a.getValue()-b.getValue());for (Map.Entry<Integer, Integer> entry: map.entrySet()) {min_heap.offer(entry);if (min_heap.size() > k) {min_heap.poll();}}int[] res = new int[k];for (int i = 0; i < k; i++) {res[i] = min_heap.poll().getKey();}return res;}
}
4.买卖股票的最佳时机
持有股票的最大金额和不持有股票
注意不持有=前一天持有+卖出
class Solution {public int maxProfit(int[] prices) {// dp[i][0] 第i天持有股票的 , dp[i][1]第i天卖出股票的最大金额int[][] dp = new int[prices.length][2];dp[0][0] = -prices[0];dp[0][1] = 0;for (int i = 1; i < prices.length; i++) {dp[i][0] = Math.max(dp[i-1][0], -prices[i]);dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);}return dp[prices.length-1][1];}
}
5.跳跃游戏(*)
定义覆盖范围,在覆盖范围内遍历
class Solution {public boolean canJump(int[] nums) {if (nums.length <= 1) return true;int cover = 0;for (int i = 0; i <= cover; i++) {cover = Math.max(cover, i+nums[i]);if (cover >= nums.length-1) return true;}return false;}
}
6.跳跃游戏2(*)
当前,覆盖距离,下一步覆盖距离
如果i到了当前覆盖距离末尾,并且没到终点,启动下一步覆盖距离
res++
class Solution {public int jump(int[] nums) {int cur = 0;int next = 0;int res = 0;for (int i = 0; i < nums.length; i++) {next = Math.max(next, i+nums[i]);if (i == cur && i < nums.length-1) {res++;cur = next;if (cur >= nums.length-1) break;}}return res;}
}
7.划分字母区间(*)
1.记录每个字母的最远距离
2.统计最大的最远距离,判断i是否到最远距离是就记录,左指针+1
class Solution {public List<Integer> partitionLabels(String s) {// 记录每个元素的最远距离Map<Character, Integer> map = new HashMap<>();for (int i = 0; i < s.length(); i++) {map.put(s.charAt(i), i);}int left = 0;int right = 0;List<Integer> list = new ArrayList<>();for (int i = 0; i < s.length(); i++) {right = Math.max(map.get(s.charAt(i)), right);if (i == right) {list.add(right-left+1);left = right+1;}}return list;}
}
8.爬楼梯
dp[n] = dp[n-1]+dp[n-2]
class Solution {public int climbStairs(int n) {// dp[n] = dp[n-1] + dp[n-2]int[] dp = new int[n+1];dp[0] = 1;dp[1] = 1;for (int i = 2; i <= n; i++) {dp[i] = dp[i-1] + dp[i-2];}return dp[n];}
}
9.杨辉三角(*)
dp[i] = dp[i-1][j-1] + dp[i-1][j];
获取集合的某个元素可以采用下标,list.get().get()
class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> res = new ArrayList<>();res.add(Arrays.asList(1));if (numRows == 1) return res;res.add(Arrays.asList(1, 1));if (numRows == 2) return res;for (int i = 2; i < numRows; i++) {List<Integer> cur = new ArrayList<>();cur.add(1);for (int j = 1; j < i; j++) {cur.add(res.get(i-1).get(j-1)+res.get(i-1).get(j));}cur.add(1);res.add(cur);}return res;}
}
10.打家劫舍
dp[i] = Math.max(dp[i-1], dp[i-2]+nums[i]);
class Solution {public int rob(int[] nums) {// dp[i] = Math.max(dp[i-1], dp[i-2]+nums[i])if (nums.length == 1) return nums[0];int[] dp = new int[nums.length];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < nums.length; i++) {dp[i] = Math.max(dp[i-1], dp[i-2]+nums[i]);}return dp[nums.length-1];}
}