leetcode分类刷题(续1)
Posted Panda_cv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode分类刷题(续1)相关的知识,希望对你有一定的参考价值。
7. 树
普通二叉树、完全二叉树、满二叉树
二叉树遍历:前序–根左右(寻找根), 中序–左中右, 后续–左右中
7.1 leetcode144 二叉树前序遍历
错误做法:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new LinkedList<>();
if(root == null)
return list;
else{
Stack<TreeNode> stack = new LinkedList<TreeNode>();
// Deque<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(root);
}
while(!stack.isEmpty()){
TreeNode node = stack.pop();
list.add(node.val);
if(root.left != null){
stack.push(root.left);
}
if(root.right != null){
stack.push(root.right);
}
}
return list;
}
}
迭代---或者DfS
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
preorder(root, res);
return res;
}
public void preorder(TreeNode root, List<Integer> res) {
if (root == null) {
return;
}
res.add(root.val);
preorder(root.left, res);
preorder(root.right, res);
}
}
7.2 leetcode94 二叉树中序遍历
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode node = root;
while (!stack.isEmpty() || node != null) {
while (node != null) {
res.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
}
7.1 leetcode145 二叉树后序遍历
// An highlighted block
var foo = 'bar';
8. 堆
最大堆、最小堆
删除元素的时间复杂度o(logN)
添加元素的时间复杂度o(logN)
**创建堆的堆化操作时间复杂度o(N)
堆的常用操作
import java.utils.Collections;
import java.util.PriorityQueue;
1. 创建堆
默认创建最小堆
PriorityQueue<Integer> minheap = new PriorityQueue<>();
创建最大堆 需要在括号加上参数
PriorityQueue<Integer> maxheap = new PriorityQueue<>(Collections.reverseOrder);
2. 增加元素
最小堆: minheap.add();
最大堆: maxheap.add();
3. 输出最小(大)堆
minheap.toString();
4. 取堆顶元素
minheap.peek();
5. 删除元素
minheap.poll();
6. 堆的大小
minheap.size();
7. 判读堆不为空
minheap.isEmpty();
8.1 leetcode215 数组中第k个最大元素
伪代码:
func(nums, k){
heap = new heap; 创建最大堆
for(num in nums)
heap.add(num);
while(k>1)
{
heap.pop();
k = k -1;
}
return heap.pop();
}
8.2 leetcode692 前k个高频单词
// 哈希表 Heap+HashTable
public class Solution {
public List<String> topKFrequent(String[] words, int k) {
// 1.先用哈希表统计单词出现的频率
Map<String, Integer> count = new HashMap();
for (String word : words) {
count.put(word, count.getOrDefault(word, 0) + 1);
}
// 2.构建小根堆 这里需要自己构建比较规则 此处为 lambda 写法 Java 的优先队列默认实现就是小根堆
PriorityQueue<String> minHeap = new PriorityQueue<>((s1, s2) -> {
if (count.get(s1).equals(count.get(s2))) {
return s2.compareTo(s1);
} else {
return count.get(s1) - count.get(s2);
}
});
// 3.依次向堆加入元素。
for (String s : count.keySet()) {
minHeap.offer(s);
// 当堆中元素个数大于 k 个的时候,需要弹出堆顶最小的元素。
if (minHeap.size() > k) {
minHeap.poll();
}
}
// 4.依次弹出堆中的 K 个元素,放入结果集合中。
List<String> res = new ArrayList<String>(k);
while (minHeap.size() > 0) {
res.add(minHeap.poll());
}
// 5.注意最后需要反转元素的顺序。
Collections.reverse(res);
return res;
}
}
10. 双指针
- 普通的双指针:两个指针往同一个方向移动
- 对撞的双指针: 两个指针面对面的移动
- 快慢的双指针:… 链表是否存在环
10.1 两个数相加为target,返回下标
- 普通的双指针:暴力算法,两个for循环。
- 对撞的双指针:1 4 5 7 9 遍历一遍。对撞适用场景----数组有序
10.2 leetcode141 环形链表
10.3 leetcode881 救生艇
//伪代码:
//对撞指针
//数组排序
people.sort();
i = 0;
j = nums.length - 1;
res = 0; 计数次数
while(i <= j){
if(nums[i]+nums[j]<= limit)
i = i + 1;
j = j - 1;
res ++;
}
return res;
11. 二叉查找
重要特点:数字有序 o(logN)
11.1 leetcode704 标准的二分查找
// 数组是否存在target
while(l < = r){
mid = l+r / 2
if(nums[mid] == target)
return mid;
else if (nums[mid] > target)
r = mid -1;
else
l = mid + 1;
}
return -1;
11.2 leetcode35 搜索插入位置
// 不存在 返回插入位置
while(l < r)
11.3 leetcode162 寻找峰值
// o(logN)
nums[m] < nums[m+1] 峰值在右边
11.4 leetcode74 搜索二维矩阵
// 二维数组升序遍历
(x,y)-----> x X col + y; 二维与一位坐标的转化
row = matrix.length
col = matrix[0].length
12. 滑动窗口
//目的: 减少while循环
//eg: a = [1,2,3,4,2,3,1], 求三个为一组的最大的和,常规做法:一次遍历 每次求出三个和的值。
// 适用场景:数组中定长问题
12.1 leetcode209 长度最小的子数组
func (){ //伪代码
int res = nums.length + 1;
int i = j = 0;
int total = 0;
while(j < nums.length){
//自己加的:if(total < target)
toral = total + nums[j];
j ++;
while(total >= target){
res = min(res, j - i);
total = total - nums[i];
i = i + 1;
}
}
if(res > = nums.length + 1)
return 0;
else
return res;
}
class Solution { //源代码
public int minSubArrayLen(int target, int[] nums) {
if(nums.length == 0)
return 0;
int i = 0;
int j = 0;
int total = 0;
int res = nums.length + 1;
while(j < nums.length){
total = total + nums[j];
j = j + 1;
while(total >= target){
res = Math.min(res,j-i);
total = total - nums[i];
i = i + 1;
}
}
if(res >= nums.length + 1)
return 0;
else
return res;
}
}
12.2 leetcode1456 定长子串中元音的最大数目
以上是关于leetcode分类刷题(续1)的主要内容,如果未能解决你的问题,请参考以下文章