当前位置: 首页 > news >正文

队列+宽度优先搜索,力扣.662.二叉树最大高度 力扣515.在每个数行中找最大值力扣703.数据流中第k大元素力扣692.前k个高频词

目录

力扣.662.二叉树最大高度 

力扣515.在每个数行中找最大值

力扣703.数据流中第k大元素

力扣692.前k个高频词


力扣.662.二叉树最大高度 

首先记录一下我的错误想法,其实也挺对的

看到这个图,感觉其实就是找两个端点[左,null,null,右]中间可以有一堆空,我是想着,把一堆空给他初始化一个节点,给他插入进队列里面,他的节点数值【100,-100】我直接-101,然后一层给他放一个List<List>>里面,然后遍历一个begin,一个end找最小和最大,一个减法就好,也能过大部分例子,72-116,心痛

这个最后估计没准树高1500,那就要2的1500次幂

解法二:使用数组存储二叉树的方式,给定节点编号

思路肯定对,但是这个刹弊题目给的数据怪,怪的同时吧,你越界,两个越界相减还是对的,但是你假如取最小值,和最大值的话,就会在越界的时候,把那个相减的对的给去除

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
  public static int widthOfBinaryTree(TreeNode root) {
        Deque<TreeNode>q=new LinkedList<>();
        root.val=1;
        q.add(root);
        int count=0;
        while(!q.isEmpty()){
            int sz=q.size();
            //记录起点的同时记录有多少个
            //每个都是从0开始编号
            int begin=Integer.MAX_VALUE;
            int end=-1;
            int t=sz;
            while(sz!=0){
                TreeNode root1=q.poll();
                //考虑一下,最左边的是不是一定最小,最右边的是不是一定最大呢?
                if(t==sz) begin=Math.min(root1.val,begin);
                if(sz==1) end=Math.max(end,root1.val);
                if(root1.left!=null) {
                    root1.left.val=(root1.val*2);
                    q.add(root1.left);
                }
                if(root1.right!=null) {
                    root1.right.val=(root1.val*2+1);
                    q.add(root1.right);
                }
                t++;
                sz--;
            }
            count=Math.max(count,(end-begin+1));
        }
        //此时已经遍历整体之后,我应该取出来每一个

        return count;
    }
}

最终正解,就是题数据恶心

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
  public static int widthOfBinaryTree(TreeNode root) {
    //使用数组模拟队列,出队列,头删一个元素麻烦,所以利用一个新的覆盖就可以啦
      List<Pair<TreeNode,Integer>>q=new ArrayList<>();
      q.add(new Pair<TreeNode,Integer>(root,1));
      int ret=0;
      //列表
      while(!q.isEmpty()){
        //先更新一下这一层的宽度,获取头部
        Pair<TreeNode,Integer>t1=q.get(0);
        //获取尾巴
        Pair<TreeNode,Integer>t2=q.get(q.size()-1);
        //更新这一层
        ret=Math.max(t2.getValue()-t1.getValue()+1,ret);
//下一层进入队列,唯一难度就是怎么让q进行插入,使用tmp存储,然后最后用tmp覆盖掉即可
    List<Pair<TreeNode,Integer>>tmp=new ArrayList<>();
     for(Pair<TreeNode,Integer>t:q){
      TreeNode node=t.getKey();
      int index=t.getValue();
      if(node.left!=null){
          tmp.add(new Pair<TreeNode,Integer>(node.left,index*2));
     }
      if(node.right!=null){
          tmp.add(new Pair<TreeNode,Integer>(node.right,index*2+1));
     }
 }
 q=tmp;
      }
        return ret;
    }
}

力扣515.在每个数行中找最大值

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        Queue<TreeNode>q=new LinkedList<>();
        q.add(root);
        List<Integer>ret=new LinkedList<>();
        if(root==null) return ret;
        while(!q.isEmpty()){
        int sz=q.size();
        int max=Integer.MIN_VALUE;
        while(sz!=0){
        TreeNode t=q.poll();
        max=Math.max(max,t.val);
        if(t.left!=null) q.add(t.left);
        if(t.right!=null) q.add(t.right);
            sz--;
        }
        ret.add(max);
        }
return ret;

    }
}

力扣703.数据流中第k大元素

数据十分友好,我觉得他没有搞很多什么构造函数的,恶心你,蛮不错了已经。

题目中大第k大元素和k个不同元素的意思是,2,2 3,3 ,1 第三大的应该是2,不是1

class KthLargest {
    PriorityQueue <Integer>q=new PriorityQueue<>();
    public int kk;
    public KthLargest(int k, int[] nums) {
    kk=k;
    if(k<=nums.length){
    //找第4大的,1,2,3,4,5
      for(int i=0;i<k;i++){
        q.add(nums[i]);
      }
     for(int i=k;i<nums.length;i++){
        if(q.peek()<nums[i]){
        q.poll();
        q.add(nums[i]);
      }
     }
       }else if(k>nums.length){
        //假如来个999大的,1,2,3,后面慢慢添加
        for(int i=0;i<nums.length;i++)    q.add(nums[i]);
       }

    }
    
    public int add(int val) {
    if(q.size()<kk) {
        q.add(val);
        return q.peek();}
        if(q.peek()<val){
            q.poll();
            q.add(val);  
        }
            return q.peek();
    }
}

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest obj = new KthLargest(k, nums);
 * int param_1 = obj.add(val);
 */

力扣692.前k个高频词

你提供的代码是一个自定义的 `Comparator`,用于对字符串列表 `ret` 进行排序。这个 `Comparator` 的逻辑如下:

1. 首先检查两个字符串在 `map` 中对应的值是否相等。
2. 如果相等,则按字母顺序(自然顺序)比较这两个字符串。
3. 如果不相等,则按照 `map` 中对应的值进行降序排序。

这是一个有效的 `Comparator` 实现,适用于对包含字符串的列表进行排序,特别是当你希望根据字符串在 `map` 中的值和它们自身的字母顺序进行排序时。

这里是你提供的代码的一个完整示例,包括创建 `map` 和 `ret` 列表,以及使用自定义 `Comparator` 对 `ret` 进行排序:


- **`map`**: 存储了每个字符串及其对应的整数值。
- **`ret`**: 是一个包含字符串的列表,我们将对这个列表进行排序。
- **`Collections.sort`**: 使用自定义的 `Comparator` 对 `ret` 列表进行排序。
- **`Comparator`**:
  - 如果 `map.get(word1)` 和 `map.get(word2)` 相等,则按字母顺序 (`word1.compareTo(word2)`) 排序。
  - 否则,按 `map` 中的值进行降序排序 (`map.get(word2) - map.get(word1)`)。

[apple, banana, cherry, date]
解释:
- `"apple"` 的值为 3,最大。
- `"banana"` 和 `"cherry"` 的值都为 2,但 `"banana"` 在字母顺序上排在 `"cherry"` 之前。
- `"date"` 的值为 1,最小。

哈希表+排序

class Solution {
public static List<String> topKFrequent(String[] words, int k) {
        //考虑,堆+哈希
        HashMap<String,Integer>map=new HashMap<>();
        PriorityQueue<String>q=new PriorityQueue<>();
        for(int i=0;i<words.length;i++){
            //记录每个单词的次数
            map.put(words[i],map.getOrDefault(words[i],0)+1);
        }
        List<String>ret=new LinkedList<>();
        //这里是遍历哈希表,全部放入链表中
使用哈希表的遍历,entrySet它用于返回映射中包含的键值对的Set视图。这个方法非常有用,因为它允许开发者遍历Map中的所有键值对。
//Map.Entry<String,Integer>就是一个相当于方便遍历的东西
        for(Map.Entry<String,Integer>entry:map.entrySet()){
            ret.add(entry.getKey());
        }
        //他的排序是排序数组,然后根据哈希表来排序
       Collections.sort(ret, new Comparator<String>() {
           @Override
           public int compare(String word1, String word2) {
               //假如两个个数一样,就去比较字母顺序
               return map.get(word1)==map.get(word2)?
                       word1.compareTo(word2):map.get(word2)-map.get(word1);
           }
       });
        //map里面存储了很多东西


     return ret.subList(0,k);
    }
}  

class Solution {
     public static List<String> topKFrequent(String[] words, int k) {
        //考虑,堆+哈希
        HashMap<String,Integer>map=new HashMap<>();
        //由大到小的排序
        for(int i=0;i<words.length;i++){
        //记录每个单词的次数
        map.put(words[i],map.getOrDefault(words[i],0)+1);
        }

        PriorityQueue<String>q=new PriorityQueue<>((String a,String b)->{//频次相同时候,字典序按照大根堆的方式排列
                return   map.get(a)==map.get(b)?b.compareTo(a):map.get(a)-map.get(b);
        });
        //字典序保证之后,我们只需要负责插入即可,插入该怎么处理?肯定是前面我先随便插入
        for(Map.Entry<String,Integer> entry:map.entrySet()){

            if(q.size()<k){
                //但是map怎么让他有序呢,他肯定是先根据顺序来
                q.add(entry.getKey());
            }else {
                if(map.get(q.peek())<map.get(entry.getKey())||
                        //两个次数一样,判断字母
                        (map.get(q.peek())==map.get(entry.getKey())&&
                                entry.getKey().compareTo(q.peek())<0))
                {
                    q.poll();
                    q.add(entry.getKey());
                }
            }
        }
        List<String>ret=new LinkedList<>();
       Stack<String> a=new Stack<>();
        while (!q.isEmpty()){
            a.add(q.poll());
        }
        while (!a.isEmpty()){
            ret.add(a.pop());
        }
        return ret;
    }


}  

class Solution {
     public static List<String> topKFrequent(String[] words, int k) {
        //考虑,堆+哈希
        HashMap<String,Integer>map=new HashMap<>();
        //由大到小的排序
        for(int i=0;i<words.length;i++){
        //记录每个单词的次数
        map.put(words[i],map.getOrDefault(words[i],0)+1);
        }

        PriorityQueue<Pair<String,Integer>>heap=new PriorityQueue<>
        ((a, b)->{//频次相同时候,字典序按照大根堆的方式排列
                if(a.getValue().equals(b.getValue())){
                    //大根堆估计就是相反次序,我总是记不清,所以实验一下会更好
                    return b.getKey().compareTo(a.getKey());
                }
                return a.getValue()-b.getValue();
        });
        //字典序保证之后,我们只需要负责插入即可,插入该怎么处理?肯定是前面我先随便插入
        for(Map.Entry<String,Integer> entry:map.entrySet()){
          heap.offer(new Pair<>(entry.getKey(),entry.getValue()));
          if(heap.size()>k){
            heap.poll();
          }
        }
//提取结果
        List<String>ret=new LinkedList<>();
       Stack<String> a=new Stack<>();
        while (!heap.isEmpty()){
            a.add(heap.poll().getKey());
        }
        while (!a.isEmpty()){
            ret.add(a.pop());
        }
        return ret;
    }
}  

相关文章:

  • Python的types库学习记录
  • todolist docker 小工具
  • 【零基础入门unity游戏开发——进阶篇】unity中配合VideoClip和VideoPlayer组件实现视频播放
  • 给单片机生成字库的方案
  • Android中实现多线程的几种方式
  • 计算机视觉——深入理解卷积神经网络与使用卷积神经网络创建图像分类算法
  • 【人工智能】人工智能安全(AI Security)
  • SQL Server表数据变更捕获的5种方法及实战对比
  • Simulink指导手册笔记①--自动创建模型
  • LeetCode 解题思路 16(Hot 100)
  • spring 创建单例 Bean 源码分析
  • itsdangerous加解密源码分析|BUG汇总
  • 大语言模型入门文献推荐
  • 每日Attention学习28——Strip Pooling
  • 【Golang】第二弹-----变量、基本数据类型、标识符
  • 上传本地项目到GitHub
  • 守护中国软件供应链安全,未名湖畔的筑梦人
  • Adobe Premiere Pro2023配置要求
  • 【Function】使用托管身份调用Function App触发器,以增强安全性
  • 深入解析 TensorFlow 兼容性问题及构建输出文件结构*
  • 展示系统 网站模板免费下载/聊城seo培训
  • 网站配色的原理和方法/百度入口
  • 网站访问量怎么做/电脑培训班零基础
  • 企业网站建设的内容/东莞百度快速排名优化
  • win2008系统asp网站建设/什么广告推广最有效果
  • 深圳企业网站建设费用明细/如何制作个人网站