Leetcode 295.数据流的中位数

news2024/9/22 20:33:54

295.数据流的中位数

问题描述

中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。

  • 例如 arr = [2,3,4] 的中位数是 3
  • 例如 arr = [2,3] 的中位数是 (2 + 3) / 2 = 2.5

实现 MedianFinder 类:

  • MedianFinder() 初始化 MedianFinder 对象。
  • void addNum(int num) 将数据流中的整数 num 添加到数据结构中。
  • double findMedian() 返回到目前为止所有元素的中位数。与实际答案相差 10-5 以内的答案将被接受。

示例 1:

输入
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
[[], [1], [2], [], [3], []]
输出
[null, null, null, 1.5, null, 2.0]

解释
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1);    // arr = [1]
medianFinder.addNum(2);    // arr = [1, 2]
medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
medianFinder.addNum(3);    // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0

提示:

  • -105 <= num <= 105
  • 在调用 findMedian 之前,数据结构中至少有一个元素
  • 最多 5 * 104 次调用 addNumfindMedian

解题思路与代码实现

思路:

设置两个优先队列(相当于堆)queMinqueMax

queMin:记录小于等于中位数的数;

queMax:记录大于中位数的数

添加元素时维持: queMax元素个数 <=queMin的元素个数 <=queMax元素个数 +1

取中位数时:

  • queMax元素个数 ==queMin的元素个数,从queMinqueMax 取出二者队头元素的平均值;
  • queMax元素个数 <queMin的元素个数,从queMin取出队头元素;

代码实现:

class MedianFinder {
    PriorityQueue<Integer> queMin; // 记录小于等于中位数的数
    PriorityQueue<Integer> queMax; // 记录大于中位数的数

    public MedianFinder() {

        queMin = new PriorityQueue<>(Comparator.reverseOrder()); // 降序排序
        queMax = new PriorityQueue<>(Comparator.naturalOrder()); // 升序排序
    }

    /**
     * 添加元素时保持:
     * queMin的元素个数 >= queMax元素个数 && queMin的元素个数 <= queMax元素个数 + 1
     */
    public void addNum(int num) {
        if (queMin.isEmpty() || queMin.peek() >= num) { // 第一个元素或者num小于等于queMin最大元素
            queMin.offer(num);
            // 尽可能保持两者元素数量相等
            if (queMin.size() > queMax.size() + 1) {
                queMax.offer(queMin.poll());
            }
        } else { // num大于queMax最小元素
            queMax.offer(num);
            // 尽可能保持两者元素数量相等
            if (queMax.size() > queMin.size()) {
                queMin.offer(queMax.poll());
            }
        }
    }

    
    public double findMedian() {
        if (queMin.size() > queMax.size()) {
            return queMin.peek();
        }
        return (queMin.peek() + queMax.peek()) / 2.0;
    }
}

155. 最小栈

问题描述

设计一个支持 pushpoptop 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

示例 1:

输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

输出:
[null,null,null,null,-3,null,0,-2]

解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

提示:

  • -231 <= val <= 231 - 1
  • poptopgetMin 操作总是在 非空栈 上调用
  • push, pop, top, and getMin最多被调用 3 * 104

解题思路与代码实现

思路:

设置辅助栈,栈中元素为长度为2的数组,分别存当前插入的val值和它插入后栈中的最小val值。

插入元素时:直接放在栈顶

  • 当前栈为空时,当前插入的val值就是插入后栈中的最小val值;
  • 当前栈为不空时,插入后栈中的最小val值要么是当前插入的val值,要么是插入前栈中的最小val值;

取出最小元素:从栈顶元素获取当前栈中的最小val值;

代码实现:

class MinStack {
    // 栈中元素为长度为2的数组,分别存当前插入的val值和它插入后栈中的最小val值
    Stack<int[]> stack = null;

    public MinStack() {
        stack = new Stack<>();
    }

    public void push(int val) {
        if (stack.isEmpty()) { // 当前堆栈为空
            stack.push(new int[] { val, val });
        } else { // 堆栈不为空
            int[] item = stack.peek();
            stack.push(new int[] { val, Math.min(item[1], val) });
        }

    }

    // 栈顶元素出栈
    public void pop() {
        stack.pop();
    }

    public int top() {
        int[] item = stack.peek();
        return item[0];
    }

    // 获取堆栈中的最小元素
    public int getMin() {
        int[] item = stack.peek();
        return item[1];
    }
}

踩坑点

栈顶元素需要记录当前栈中最小的val值

37. 解数独

问题描述

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:

img

输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]
输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
解释:输入的数独如上图所示,唯一有效的解决方案如下所示:

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

解题思路与代码实现

思路:

回溯暴力解,给回溯函数设置返回值,当找到一个可行解时,停止计算,返回结果。

代码实现:

class Solution {
    private final int N = 9;

    public void solveSudoku(char[][] board) {
        backtracking(board, 0, 0);
    }

    /**
     * 回溯函数
     * 设置返回值是为了当找到一个可行解时,停止计算,返回结果
     *
     * @return flag 是否找到了唯一的解
     */
    private boolean backtracking(char[][] board, int row, int col) {
        if (row == N) { // 遍历了整个棋盘返回true
            return true;
        }
        // 当前位置已有数字,去处理下一位置
        if (board[row][col] != '.') {
            int nextRow = col == N - 1 ? row + 1 : row;
            int nextCol = col == N - 1 ? 0 : col + 1;
            boolean flag = backtracking(board, nextRow, nextCol);
            return flag;
        }

        for (char k = '1'; k <= '9'; k++) {
            // 用1-9在当前位置尝试
            if (isValid(board, row, col, k)) {
                board[row][col] = k;
                int nextRow = col == N - 1 ? row + 1 : row;
                int nextCol = col == N - 1 ? 0 : col + 1;
                boolean flag = backtracking(board, nextRow, nextCol);
                if (flag) { // 找到了可行解,停止计算
                    return true;
                }
                board[row][col] = '.'; // 回溯
            }
        }
        // 用1-9在当前位置都不满足,返回false
        return false;
    }

    /**
     * 判断当前位置是否有效
     */
    private boolean isValid(char[][] board, int row, int col, char c) {
        // 判断同一行或者同一列是否有重复数字
        for (int i = 0; i < N; i++) {
            if (c == board[row][i] // 同一行
                    || c == board[i][col]) { // 同一列
                return false;
            }
        }
        // 判断3*3区域是否有重复数字
        int startX = row / 3 * 3;
        int startY = col / 3 * 3;
        for (int i = startX; i < startX + 3; i++) {
            for (int j = startY; j < startY + 3; j++) {
                if (c == board[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

}

踩坑点

判断当前位置试探的数字在所在的3*3棋盘是否重复

71.简化路径

问题描述

给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。

在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。

请注意,返回的 规范路径 必须遵循下述格式:

  • 始终以斜杠 '/' 开头。
  • 两个目录名之间必须只有一个斜杠 '/'
  • 最后一个目录名(如果存在)不能'/' 结尾。
  • 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.''..')。

返回简化后得到的 规范路径

示例 1:

输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。 

示例 2:

输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。

示例 3:

输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。

示例 4:

输入:path = "/a/./b/../../c/"
输出:"/c"

提示:

  • 1 <= path.length <= 3000
  • path 由英文字母,数字,'.''/''_' 组成。
  • path 是一个有效的 Unix 风格绝对路径。

解题思路与代码实现

思路:

使用辅助栈求解,先对字符串先切片,遍历字符串数组判断:

  • 如果不是空串且不是".“且不是”…",加入到栈;
  • 如果是".",跳过,不作任何处理;
  • 如果是"…"且栈不为空,弹出栈顶元素;

最后拼接栈中字符串返回。

代码实现:

class Solution {
    public String simplifyPath(String path) {
        String[] strs = path.split("/"); // 字符串切片
        Stack<String> stack = new Stack<>(); // 辅助栈
        for (String str : strs) {
            // 切片后:当前字符串不为空串也不为.和..,加入到栈中
            if (!str.equals("") && !str.equals(".") && !str.equals("..")) {
                stack.push(str);
            } else if (str.equals("..") && !stack.isEmpty()) {
                // 当前字符串为..且栈中不为空,则弹出栈顶元素
                stack.pop();
            }
        }
        if (stack.isEmpty()) { // 栈为空,返回根目录
            return "/";
        }
        // 拼接栈中字符串
        StringBuilder builder = new StringBuilder();
        while (!stack.isEmpty()) {
            builder.insert(0, "/" + stack.pop());
        }
        return builder.toString();
    }
}

踩坑点

没想到字符串切片,纯指针实现切片,代码臃肿。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1907794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redis运维:sentinel模式如何查看所有从节点

1. 连接到sentinel redis-cli -h sentinel_host -p sentinel_port如&#xff1a; redis-cli -h {域名} -p 200182. 发现Redis主服务器 连接到哨兵后&#xff0c;我们可以使用SENTINEL get-master-addr-by-name命令来获取当前的Redis主服务器的地址。 SENTINEL get-master-a…

STM32对数码管显示的控制

1、在项目开发过程中会遇到STM32控制的数码管显示应用&#xff0c;这里以四位共阴极数码管显示控制为例讲解&#xff1b;这里采用的控制芯片为STM32F103RCT6。 2、首先要确定数码管的段选的8个引脚连接的单片机的引脚是哪8个&#xff0c;然后确认位选的4个引脚连接的单片机的4…

SpringBoot 启动流程六

SpringBoot启动流程六 这句话是创建一个上下文对象 就是最终返回的那个上下文 我们这个creatApplicationContext方法 是调用的这个方法 传入一个类型 我们通过打断点的方式 就可以看到context里面的东西 加载容器对象 当我们把依赖改成starter-web时 这个容器对象会进行…

【网络安全】对称加密算法

文章目录 非对称加密对称加密&#xff1a;Des 加密3 DES 加密Des 加密java ApiAES 加密算法AES 加密过程AES 密钥拓展 非对称加密 非对称加密算法需要两个密钥&#xff1a;公开密钥&#xff08;publickey:简称公钥&#xff09;和私有密钥&#xff08;privatekey:简称私钥&…

一键配置PCL环境+VTK环境(最简单的方法)

系列文章目录 1. Windows系统下5分钟配置好PCL&#xff08;debug和release&#xff09; 2. PCL1.11.0Qt5.14.2VTK8.2VS2019 环境配置&#xff08;超详细&#xff09; 文章目录 系列文章目录前言一、下载解压文件二、双击运行Setup.bat三、测试视频四、所需文件 前言 之前写过…

Android 开发中 C++ 和Java 日志调试

在 C 中添加堆栈日志 先在 Android.bp 中 添加 ‘libutilscallstack’ shared_libs:["liblog"," libutilscallstack"]在想要打印堆栈的代码中添加 #include <utils/CallStack.h> using android::CallStack;// 在函数中添加 int VisualizerLib_Crea…

20240708 每日AI必读资讯

&#x1f916;破解ChatGPT惊人耗电&#xff01;DeepMind新算法训练提效13倍&#xff0c;能耗暴降10倍 - 谷歌DeepMind研究团队提出了一种加快AI训练的新方法——多模态对比学习与联合示例选择&#xff08;JEST&#xff09;&#xff0c;大大减少了所需的计算资源和时间。 - JE…

python基础篇(9):模块

1 模块简介 Python 模块(Module)&#xff0c;是一个 Python 文件&#xff0c;以 .py 结尾. 模块能定义函数&#xff0c;类和变量&#xff0c;模块里也能包含可执行的代码. 模块的作用: python中有很多各种不同的模块, 每一个模块都可以帮助我们快速的实现一些功能, 比如实现…

实在智能荣获WAIC 2024机器之心重量级奖项——AI隐形冠军TOP 10!

近日&#xff0c;世界人工智能大会&#xff08;WAIC 2024&#xff09;如火如荼召开&#xff0c;自2018年首届举办以来&#xff0c;WAIC已成为全球AI领域最具影响力的国际盛会之一。本届WAIC再度集聚了来自世界各地的政府代表、顶尖科学家、行业领袖和创新企业等&#xff0c;共同…

Redis存储原理与数据模型

Redis存储结构 存储转换 redis-value编码 string int&#xff1a;字符串长度小于等于20切能转成整数raw&#xff1a;字符串长度大于44embstr&#xff1a;字符串长度小于等于44 list quicklist&#xff08;双向链表&#xff09;ziplist&#xff08;压缩链表&#xff09; hash …

7.8作业

一、思维导图 二、 1】按值修改 2】按值查找&#xff0c;返回当前节点的地址 &#xff08;先不考虑重复&#xff0c;如果有重复&#xff0c;返回第一个&#xff09; 3】反转 4】销毁链表 //按值修改 int value_change(linklistptr H,datatype e,int value) {if(HNULL||empty(H…

自动化测试及生成测试报告

Linux安装Selenium进行自动化测试 首先需要安装python、Chrome&ChromeDirver ChromeDriver与Chrome对应版本 #查看chrome版本google-chrome --version或者在浏览器搜索chrome://version/ChromeDriver下载地址这里下载114版本 wget https://chromedriver.storage.googleap…

数据库图形化管理界面应用 Navicat Premium 使用教程

经同学介绍的一个把数据库可视化的软件Navicat Premium&#xff0c;很好用&#xff0c;在这里分享一下&#xff0c;需要的同学可以去了解看看 一&#xff1a;下载并解压 链接&#xff1a;https://pan.baidu.com/s/1ZcDH6m7EAurAp_QmXWx81A 提取码&#xff1a;e5f6 解压到合…

Windows下载、配置Java JDK开发环境的方法

本文介绍在Windows电脑中&#xff0c;安装JDK&#xff08;Java Development Kit&#xff09;&#xff0c;也就是Java开发工具包的详细方法。 JDK是Java软件开发的基础&#xff0c;由Oracle公司提供&#xff0c;用于构建在Java平台上运行的应用程序与组件等&#xff1b;其已经包…

CnosDB:深入理解时序数据修复函数

CnosDB是一个专注于时序数据处理的数据库。CnosDB针对时序数据的特点设计并实现了三个强大的数据修复函数&#xff1a; timestamp_repair – 对时间戳列进行有效修复&#xff0c;支持插入、删除、不变等操作。value_repair – 对值列进行智能修复&#xff0c;根据时间戳间隔和…

Django 新增数据 save()方法

1&#xff0c;添加模型 Test/app11/models.py from django.db import modelsclass Book(models.Model):title models.CharField(max_length100)author models.CharField(max_length100)publication_date models.DateField()price models.DecimalField(max_digits5, decim…

数据分析与挖掘实战案例-电商产品评论数据情感分析

数据分析与挖掘实战案例-电商产品评论数据情感分析 文章目录 数据分析与挖掘实战案例-电商产品评论数据情感分析1. 背景与挖掘目标2. 分析方法与过程2.1 评论预处理1. 评论去重2. 数据清洗 2.2 评论分词1. 分词、词性标注、去除停用词2. 提取含名词的评论3. 绘制词云查看分词效…

OS-HACKNOS-2.1

确定靶机IP地址 扫描靶机开放端口信息 目录扫描 访问后发现个邮箱地址 尝试爆破二级目录 确定为wordpress站 利用wpscan进行漏洞扫描 #扫描所有插件 wpscan --url http://192.168.0.2/tsweb -e ap 发现存在漏洞插件 cat /usr/share/exploitdb/exploits/php/webapps/46537.txt…

用例导图CMind

突然有一些觉悟&#xff0c;程序猿不能只会吭哧吭哧的低头做事&#xff0c;应该学会怎么去展示自己&#xff0c;怎么去宣传自己&#xff0c;怎么把自己想做的事表述清楚。 于是&#xff0c;这两天一直在整理自己的作品&#xff0c;也为接下来的找工作多做点准备。接下来…

Tomcat的负载均衡、动静分离

一、如何tomcat和nginx负载均衡及动静分离&#xff1a;2台tomcat&#xff0c;3台nginx来实现 1.首先设置tomcat1和tomcat2服务器 关闭两台tomcat的防火墙及安全机制&#xff1a;systemctl stop filwalld setenforce 0 进入tomcat目录的webapps中&#xff0c;创建test 2.配…