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. 双指针

  1. 普通的双指针:两个指针往同一个方向移动
  2. 对撞的双指针: 两个指针面对面的移动
  3. 快慢的双指针:… 链表是否存在环

10.1 两个数相加为target,返回下标

  1. 普通的双指针:暴力算法,两个for循环。
  2. 对撞的双指针: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)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode刷题笔记-数据结构-day2

leetcode分类刷题

leetcode刷题题目分类

leetcode刷题分类笔记

leetcode刷题分类笔记

Leetcode刷题笔记-数组