IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法题小记 -> 正文阅读

[数据结构与算法]算法题小记

文章目录

一、TOPK问题

技巧,中等题就用优先队列,难题就用二分法

优先队列:
在这里插入图片描述

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
               int[] result = new int[k];
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
        // 根据map的value值正序排,相当于一个小顶堆
        PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue());
        for (Map.Entry<Integer, Integer> entry : entries) {
            queue.offer(entry);
            if (queue.size() > k) {
                queue.poll();
            }
        }
        for (int i = k - 1; i >= 0; i--) {
            result[i] = queue.poll().getKey();
        }
        return result;

    }
}

二分法:

在这里插入图片描述
上面面这题如果用优先队列的话,是可能会产生内存限制
在这里插入图片描述
因此提出了二分查找法:

二分查找算法步骤:

  • 初始化 left = 1, right = m*n, 进行二分搜索找到 k-th小数字。
  • 我们使用自定义的getCount函数来计算当前矩阵中小于等于mid值的数字数量。
  • 当二分搜索结束后,如果当前count < k,那么我们应该调整left值将其变大使得新的mid能逼近k, 及left = mid + 1
  • 反之count >= k,那么我们应该调整right值将其变小使得新的mid也能逼近k, 及right = mid

getCount()方法
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
以此类推

代码:

class Solution {

    // 寻找比小于等于mid的数字个数
    public int getCount(int mid, int m, int n){
        // 从左下角往右上角进行遍历
        int i=m,j=1;
        int count=0;
        while(i>=1&&j<=n){
            if(i*j<=mid){
                count+=i;  
                j++;  // 往右升一列
            }else{
                i--;  // 往上升一行
            }
        }

        return count;

    }


    public int findKthNumber(int m, int n, int k) {

        int left = 1, right = m*n;
        while(left<right){
            // 求中间值
            int mid = (left+right)/2;
            int count = getCount(mid,m,n);
            if(count>=k){
                // count>=mid时,mid有可能为答案,所以right=mid;比如{1,2,2,2,2}中小于等于2的数有5个,我们找第2小的数,(5>2)但是2为答案
                right=mid;
            }
            if(count<k){
                // count<k 时,mid一定不是答案,所以
                left = mid+1;

            }

        }
        return left;
        
        

    }
}

关于最后的mid一定会在数组中的问题:

我们先看getCount()函数
getCount()函数的目的是统计矩阵里小等于mid的元素数目count. 再判断count和k的关系.因为mid = (left + right) / 2这种划分方法是把矩阵划分成了[left , mid] 与[mid + 1, right]两部分. 当 count < k 时, 说明mid太小了, 我们应该在[mid + 1, right] 这个范围里查找. 否则在[left, mid]范围里查找.

如果存在一个不在矩阵中的数a满足条件, 因为a不在矩阵中,那count统计的元素肯定都是小于a的, 那一定存在一个比a小且在矩阵中的数b满足条件,即从小于a的数变成了小于等于b的数 .等用题目中的例子,x = 13 和x = 14 都满足小于等于x的元素数目等于8, 对14来说统计的都是小于它的数, 而对13来说统计的都是小于等于它的数. 问题来了, 那为何取到的不是14而是13呢?

因为我们取mid的取法是 mid = (left + right) / 2, 当left < right时, mid 永远 取不到right, 想要mid取到right ,只有left == right. 但循环条件是 while(left < right), 当 left == right时循环已经终止. 所以我们得到会是一个左边界. 还是用题目中的例子, 假设left = 13, right = 14mid = (13 + 14) / 2 = 13

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 19:13:41  更:2022-05-21 19:15:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 0:48:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码