高级算法学习day2

优先队列 Priority Queue

与普通队列的区别
保证每次取出的元素是队列中优先级最高的。优先级别可自定义(可以是数值越小优先级别越高或数值越大优先级别越高)
本质
二叉堆的结构,堆在英文里叫 Binary Heap
利用一个数组结构来实现完全二叉树(数组中的各个元素有其他元素作为子节点或者父节点)
特性
数组里的第一个元素array[0]拥有最高的优先级
对于给定一个下标i,那么对于元素array[i]而言
父节点:对应的元素下标是(i-1)/2
左侧子节点:对应的元素下标是2i+1
右侧子节点:对应的元素下标是2
i+2
数组中每个元素的优先级都必须要高于它俩侧子节点
最基本的操作有俩个:
向上筛选:当加入一个新元素,先放在最底端,然后跟父节点进行比较,新元素优先级高则交换,直到结束。时间复杂度 OlogK
向下筛选:当弹出头结点,先将头节点一直往下爬,和左子节点交换,到最底端后,弹出。时间复杂度OlogK
初始化一个优先队列的时间负责度是On
leecode347.前K个高频元素
实现:
循环用map集合存放元素和出现的次数
将map的entry存入PriorityQueue里面 ,比较器是元素的个数
让弹出前k个元素,存入数组中返回

//给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 
//
// 
//
// 示例 1: 
//
// 输入: nums = [1,1,1,2,2,3], k = 2
//输出: [1,2]
class Solution {
    public Map<Integer,Integer> map=new HashMap<>();
    public int[] topKFrequent(int[] nums, int k) {
        for (int num : nums) {
            map.put(num,map.getOrDefault(num,0)+1);
        }
        PriorityQueue<Map.Entry<Integer,Integer>> queue=new PriorityQueue<>(( o1,  o2)-> {
            return o2.getValue()-o1.getValue();
        });
        queue.addAll(map.entrySet());
        int[] result=new int[k];
        for (int i = 0; i <k ; i++) {
            result[i]=queue.poll().getKey();
        }
        return result;
    }
}

图 Graph

基本知识点:
阶,度
树,森林,环
有向图,无向图,完全有向图,完全无向图
连通图,连通分量
图的存储与表达方式:邻接矩阵,邻接链表
围绕图的算法:
图的遍历:深度优先,广度优先
环的检测:有向图,无向图
拓扑排序
最短路径算法:
连通性相关算法:Kosaraju ,Tarjan,求解孤岛的数量,判断是否为树
图的着色,旅行商问题等
必须熟练掌握的知识点
图的存储和表达方式:邻接矩阵,邻接链表
图的遍历:深度优先,广度优先
二部图的检测,树的检测,环的检测:有向图,无向图
拓扑排序,联合查找算法,最短路径算法
leecode785.判断二分图

给定一个无向图graph,当这个图为二分图时返回true//
// 如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。 
//
// graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自
//环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。 
//
// 
//
//示例 1:
//输入: [[1,3], [0,2], [1,3], [0,2]]
//输出: true
//解释: 
//无向图如下:
//0----1
//|    |
//|    |
//3----2
//我们可以将节点分成两组: {0, 2} 和 {1, 3}。
我还不会写

前缀树 Trie

  • 也称为字典树 (这种数据结构被广泛地运用于字典查找当中)
  • 字典查找
    给定一系列构成字典的字符串,要求在字典当中找出所有以“ABC”开头的字符串
    重要性质
    每个节点至少包含俩个基本属性
  • children:数组或者集合,罗列出每个分支当中包含的所有字符
  • isEnd:布尔值,表示该节点是否为某字符串的结尾
    根节点是空的
    除了根节点,其他所有节点都有可能是单词的结尾,叶子节点一定都是单词的结尾
    最基本的操作
    创建方法
    遍历一遍输入的字符串,对每个字符串的字符进行遍历
    从前缀树的根节点开始,将每个字符加入到节点的children字符集当中
    如果字符集已经包含了当前这个字符,跳过
    如果当前字符是某一个字符串的最后一个,把当前字符的isEnd标记为真
    搜索方法
    从前缀树的根节点出发,逐个匹配输入的前缀字符
    如果遇到了,继续往下一层搜索
    如果没遇到,立即返回
    leecode212.单词搜索||
//给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。 
//
// 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
//
// 示例: 
//
// 输入: 
//words = ["oath","pea","eat","rain"] and board =
//[
//  ['o','a','a','n'],
//  ['e','t','a','e'],
//  ['i','h','k','r'],
//  ['i','f','l','v']
//]
//
//输出: ["eat","oath"] 
//
// 说明: 
//你可以假设所有输入都由小写字母 a-z 组成。 

线段树 Segment Tree

一种按照二叉树的形式存储数据的结构,每个节点保存的都是数组里某一段的总和
=leecode315.计算右侧小于当前元素的个数

//给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 num
//s[i] 的元素的数量。 
//
// 示例: 
//
// 输入:nums = [5,2,6,1]
//输出:[2,1,1,0] 
//解释:
//5 的右侧有 2 个更小的元素 (2 和 1)
//2 的右侧仅有 1 个更小的元素 (1)
//6 的右侧有 1 个更小的元素 (1)
//1 的右侧有 0 个更小的元素

树状数组 Fenwick Tree

  • 也被称为 Binary Indexed Tree
    例题
    假设我们有一个数组array[0…n-1],里面有n个元素,现在我们要经常对这个数组做俩件事:
  1. 更新数组元素的数值
  2. 求数组前k个元素的总和(或者平均值)
    方法一:线段树 time:O(logn)
    方法二:树状数组 time:O(logn)
    基本特征
    利用数组来表示多叉树的结构,和优先队列有些类似
    优先队列是用数组来表示完全二叉树,而树状数组是多叉树
    树状数组的第一个节点是空节点
    如果节点tree[y]是tree[x]的父节点,那么需要满足y=x-(x&(-x))
    leecode308.二维区域和检索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值