Leetcode算法题笔记(3)

目录

  • 矩阵
    • 101. 生命游戏
      • 解法一
      • 解法二
    • 102. 移掉 K 位数字
      • 解法一
    • 103. 去除重复字母
      • 解法一

矩阵

101. 生命游戏

根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。

进阶:

你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
在这里插入图片描述

解法一

非原地算法:将矩阵复制一份,遍历旧矩阵每个元素的周围8个元素,计算存活细胞数量,再根据规则在新矩阵上进行修改,返回新矩阵(一下阶段状态矩阵)。空间复杂度过高O(mn)。

解法二

原地算法:空间复杂度过高O(1)。可以找一个复合状态同时表示旧状态和新状态,例如定义:

  • 如果细胞从活着变为死了,则复合状态为2;
  • 如果细胞从死了变成活了,则符合状态为3;
    之后便可按照算法一遍历元素,判断周围存活元素时,需要参考过去的状态,即值为1或2。最后重新遍历矩阵,将2,3变为对应的最新状态值0 , 1
class Solution {
    public void gameOfLife(int[][] board) {
        //定义如果细胞从活着变为死了,则复合状态为2;
        //如果细胞从死了变成活了,则符合状态为3;
        int row = board.length;
        int col = board[0].length;
        int[] neighbors = {-1,0,1};

        for(int i = 0; i < row ; ++i ){
            for(int j = 0; j < col ; ++j){
                int liveCount = 0;

                for(int e = 0;  e < 3 ; ++e){
                    for(int f = 0; f < 3; ++f){
                        if(!(neighbors[e] == 0 && neighbors[f] == 0)){
                            int r = neighbors[e] + i;
                            int c = neighbors[f] + j;

                            if((r >= 0 && r < row) && (c >= 0 && c < col) && ( board[r][c] == 1 || board[r][c]  == 2)){++liveCount;}
                        }
                    }
                }
                if(board[i][j] == 1 && ( liveCount < 2 || liveCount > 3 )){
                    board[i][j] = 2;
                }else if(board[i][j] == 0 && liveCount == 3){
                    board[i][j] = 3;
                }

            }
        }

        for(int i = 0; i < row ; ++i ){
            for(int j = 0; j < col ; ++j){
                if(board[i][j] == 2) board[i][j] = 0;
                if(board[i][j] == 3) board[i][j] = 1;
            }
        }

    }
}

102. 移掉 K 位数字

给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
在这里插入图片描述

解法一

        单调栈+贪心算法:为了得到尽可能小的数字,其和位数以及高位上的数字大小是相关的。如果前面高位数(高到低)都是升序的,那么这个数是这些每位上的数所能排列出的最小整数,例如123 是 1,2,3能组成的最小数。因此,借鉴这一点,可以利用贪心思想,遍历字符串,每次尽可能得到最小的数,直至到末尾。
        维持一个当前最小的数需要使用一个单调栈,保证数字是升序排列。如果遇到比栈顶元素还要小的数,那么栈顶元素就应该弹出移除(且k-1),直至k为0(删除完成)或者当前元素比栈顶元素大(则需要将当前元素压栈,此时栈中又是一个升序栈)。例如124532,k = 3 ,当遍历到3时,4,5需要出栈,之后为1232,此时3需要出栈,最终结果为122
        有种可能情况:遍历完字符串后,单调栈已经是升序,但是k还不为0,依然需要删除数字,那么此时直接从最低位开始删即可,因为删除一位数字的总位数将会固定,而最低位数字最大,且能保证前面的数字依旧是排列最小的数,例如12345,删除5后,结果为1234。

class Solution {
    public String removeKdigits(String num, int k) {
        Deque<Character> list = new LinkedList<>();
        int len = num.length();
        for(int i = 0; i < len; ++i){
            char c = num.charAt(i);
            // int numi = Character.getNumericValue(c);
            while( !list.isEmpty() && k > 0 && list.peek() > c ){
                list.pop();
                k--;
            }
            list.push(c);
        }

        while(k > 0){
            list.pop();
            k--;
        }

        StringBuilder res = new StringBuilder();
        boolean flag = true;//用于判断数字最前端是否是连续0
        while(!list.isEmpty()){
            char digit = list.pollLast();
            if(flag && digit == '0'){
                continue;
            }
            flag = false;
            res.append(digit);
        }

        return res.length() == 0 ? "0" : res.toString();
    }
}

103. 去除重复字母

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的
字典序
最小(要求不能打乱其他字符的相对位置)。
在这里插入图片描述

解法一

        单调栈+贪心算法:根据题目可知,要求每个字母只能出现一次,且这些字母组成的字典序最小。当字符呈升序排列(a b c d e f…)时,字典序是最小的时候,因此可以尝试采用单调栈来维持最小字典序的子串。此外,尝试将其与贪心思想结合,遍历字符串,每次均保证当前单调栈维持的就是目前字典序最小的子串,进而推导出最终字典序最小的子串。

  • 遍历元素过程中,如果栈为空或者当前元素相较于栈顶元素是升序,则可以直接将当前元素压栈
  • 如果当前元素已经在栈中出现过,则可以直接丢弃当前元素。因为单调栈维持的是最小字典序的子串了,如果强行将该元素放入栈中,只可能会造成字典序增大或者无变化。例如栈中acd 当前c ,最多也只能让c 和 d 出栈,然后将当前c压栈,最后栈中为ac,得到的结果其实与原栈中acd前半部分几乎一样,但是少了d的信息。让当前c是否压栈对整体的最小字典序没有益处,并不能减小字典序,反而如果d是最后一个d了,那么d必须存在,则c无法压栈。因此当元素已经出现在栈中时,没有必要将其压栈处理。
  • 如果出现了与单调栈栈顶元素大小顺序不符元素,即需要看情况丢弃当前元素还是丢弃栈中的元素。如果该栈顶元素在字符串后面已经不存在同样的元素了,则说明该元素不能在被丢弃了,后续直接入栈当前元元素如果该栈顶元素在字符串后面还存在,则说明可以丢弃当前栈顶元素,由于栈中可能有连续几个比当前元素大的元素,所以可能会连续多出栈几个元素。例如 acbc ,栈中元素为ac,当前元素b,则c后面还有,因此可以弹出c ,压栈b,压栈最后一个c,即可得到比acb更小的字典序子串abc
class Solution {
    public String removeDuplicateLetters(String s) {
        Deque<Character> stack = new LinkedList<>();
        int len = s.length();
        boolean[] numVisit = new boolean[26];
        int[] count = new int[26];
        //初始化字符串中各字符的频次
        for(int i = 0; i < len ; ++i){
            count[s.charAt(i) - 'a']++;
        }

        for(int i = 0; i <len ;++i){
            char c = s.charAt(i);
            count[c - 'a']--;
            //说明元素已经存在于单调栈中,因此可以直接丢弃
            if(numVisit[c - 'a'] == true){
                continue;
            }

            //如果出现了与单调栈栈顶元素大小顺序不符元素,即需要看情况丢弃当前元素还是丢弃栈中的元素
            if(!stack.isEmpty() && stack.peek() >= c ){
                //如果元素小于栈顶元素,则说明有可能用当前元素替换栈顶元素以得到更小的字典序
                while(!stack.isEmpty() && stack.peek() > c){
                    //如果该栈顶元素在字符串后面已经不存在同样的元素了,则说明该元素不能在被丢弃了,后续直接入栈当前元素
                    if(count[stack.peek() - 'a'] == 0){
                        break;
                    }
                    //如果该栈顶元素在字符串后面还存在,则说明可以丢弃当前栈顶元素
                    numVisit[stack.poll() - 'a'] = false;
                }
                //让比之前栈顶元素更小的当前元素入栈
                stack.push(c);
                numVisit[c - 'a'] = true;
            }
            else{
                //当前元素符合单调栈中的单调性,因此直接压栈即可
                numVisit[c - 'a'] = true;
                stack.push(c);
            }
        }
        StringBuilder res = new StringBuilder();
        while(!stack.isEmpty()){
            res.append(stack.pollLast());
        }
        return res.toString();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Thingsboard规则链:Customer Details节点详解

在物联网&#xff08;IoT&#xff09;平台Thingsboard的规则引擎体系中&#xff0c;Customer Details节点是一个功能强大的组件&#xff0c;它专为处理与客户&#xff08;Customer&#xff09;实体相关的综合信息而设计。这个节点不仅能够读取客户的基本属性&#xff0c;还能提…

【简单介绍下idm有那些优势】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

人工智能在乳腺癌领域的最新进展|【医学AI·文献速递·05-29】

小罗碎碎念 2024-05-29&#xff5c;文献速递 今天分享的文章&#xff0c;主题是AI乳腺癌。 第三篇文章&#xff0c;个人觉得是今天最有借鉴价值的——临床故事接地气&#xff0c;工科算法赶潮流。这篇文章主要做的事情是利用多模态多组学&#xff0c;去区分乳腺腺病和乳腺癌&a…

利用QtScrcpy与Power Automate 实现微信群批量自动清理

Power Automate 一、Power Automate window系统自带软件 在开始使用Power Automate之前&#xff0c;需要熟悉它的基本概念和功能。Power Automate的核心概念包括触发器、操作和连接器。触发器是指触发自动化流程的事件&#xff0c;操作是指在自动化流程中执行的操作&#xff0…

利润而不是损失:谁信任你的游戏本地化

中国游戏市场巨大且前景广阔。这尤其适用于移动游戏&#xff1a;Statista预测&#xff0c;2024年。它的收入将达到346.6亿美元。然而&#xff0c;这种巨大的财务潜力也有其反面&#xff1a;游戏进入市场的次数越多&#xff0c;它们就越难以相互争夺玩家的注意力。此外&#xff…

服务器端请求伪造--SSRF

SSRF 简介 ##SSRF定义 SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由 攻击者构造形成&#xff0c;由服务端发起请求 的一个安全漏洞。一般情况下&#xff0c;SSRF攻击的目标是从 外网无法访问的内部系统&#xff08;正是因为它是由服务端发起的&#xff0c;所…

RAID配置实战

概念 raid磁盘阵列&#xff1a;可以用不同的硬盘分区&#xff0c;组成一个逻辑上的硬盘。具有高可用 raid级别&#xff1a; raid0 &#xff1a;条带化存储&#xff1a;数据分散在多个物理硬盘上的存储方式。利用多个磁盘并行读取和写入。存储性能和读写性能是最好的。没有冗…

国产可视化爬虫助力AI大模型训练:精准爬取汉语词典

大语言模型&#xff0c;可以生成流畅对话的会话聊天机器人、通畅起草文章的内容生成器。在炫酷技术的背后&#xff0c;数据、算力、算法&#xff0c;被视作生成式AI的三个核心要素。由此可见&#xff0c;高质量的训练数据对于AI算法的准确性至关重要。 如何获得高质量的训练数…

工控一体机7寸显示器电容触摸屏(YR07JK)产品规格说明书

如果您对工控一体机有任何疑问或需求&#xff0c;或者对如何集成工控一体机到您的业务感兴趣&#xff0c;可移步控芯捷科技。 一、硬件功能介绍 1.1 YR07JK介绍 YR07JK工控机是我公司推出的一款新型 Cortex-A17 架构&#xff0c;主频达1.8GHz、具有高性能低能耗的工业控制板卡…

CSS浮动详细教学(CSS从入门到精通学习第四天)

css第04天 一、其他样式 1、圆角边框 在 CSS3 中&#xff0c;新增了圆角边框样式&#xff0c;这样我们的盒子就可以变圆角了。 border-radius 属性用于设置元素的外边框圆角。 语法&#xff1a; border-radius:length; 参数值可以为数值或百分比的形式如果是正方形&…

消费者组到底是什么?no.15

Kafka的消费者组。 消费者组&#xff0c;即Consumer Group&#xff0c;应该算是Kafka比较有亮点的设计了。那么何谓Consumer Group呢&#xff1f;用一句话概括就是&#xff1a;Consumer Group是Kafka提供的可扩展且具有容错性的消费者机制。既然是一个组&#xff0c;那么组内必…

python-使用API

python-使用API 使用github的api-即url地址请求数据 https://api.github.com/search/repositories?qlanguage:python&sortstars #这个调用返回GitHub当前托管了多少个Python项目&#xff0c;还有有关最受欢迎的Python仓库的信息。在浏览器中输入上面地址可以看到该接口&…

HCIA--DHCP: 动态主机配置协议 (复习)

DHCP: 动态主机配置协议 -- 同一分发管理ip地址 基于UDP 67/68端口工作 网络中存在DHCP的服务器为需要自动生成ip地址的设备分配ip地址&#xff1b;--C/S模型 成为DHCP服务器的条件&#xff1a; 该设备存在接口或网卡连接到所要分发ip地址的广播域内该接口或网卡必须已经配置…

从零开始利用MATLAB进行FPGA设计(六)用ADC采集信号教程1

黑金的教程做的实在太拉闸了&#xff0c;于是自己摸索信号采集模块的使用方法。 ADC模块&#xff1a;AN9238 FPGA开发板&#xff1a;AX7020&#xff1b;Xilinx 公司的 Zynq7000 系列的芯片XC7Z020-2CLG400I&#xff0c;400引脚 FBGA 封装。 往期回顾&#xff1a; 从零开始利…

鸿蒙开发【实现页面路由跳转】接上一个微博页面

给顶部最左边的日历图标设置点击事件实现页面跳转 需要展示页面内容示例图&#xff1a; 6.1.1.设置页面头部内容 新建一个页面命名为MydailyPage &#xff0c;给整个页面设置背景属性 代码如下&#xff1a; Entry Componentstruct MydailyPage { build() { Column() { …

AI生成四季变化解决方案,四季之美,一图尽揽

随着AI技术已经渗透到我们生活的方方面面&#xff0c;在这个充满变化的时代&#xff0c;美摄科技以其前沿的AI生成技术&#xff0c;为企业带来了全新的视觉体验——AI生成四季变化解决方案。这一方案不仅能够让车辆实拍的照片焕发不同季节的风采&#xff0c;更能在不改变原图构…

SheetJS V0.17.5 导入 Excel 异常修复 Invalid HTML:could not find<table>

导入 Excel 提示错误&#xff1a;Invalid HTML:could not find<table> 检查源代码 发现 table 属性有回车符 Overview: https://docs.sheetjs.com/docs/ Source: https://git.sheetjs.com/sheetjs/sheetjs/issues The public-facing websites of SheetJS: sheetjs.com…

电脑msvcp140_atomic_wait.dll丢失的高效率解决方法,快速的一键修复

我们常常遇到各种不可预见的电脑故障问题&#xff0c;msvcp140_atomic_wait.dll丢失是一个常见的系统错误&#xff0c;它通常发生在Windows操作系统中&#xff0c;特别是当用户尝试运行依赖于Microsoft Visual C Redistributable的应用程序时。该问题可能导致程序崩溃或无法启动…

【C language】判断一个正整数是否是2^n

题解&#xff1a;判断一个正整数是否是2^n(位运算方法) 1.题目 判断一个正整数是否是2^n 2.位运算法 思路&#xff1a;干掉二进制最右边的1&#xff0c;看是否是0 int main() {int num 16;if ((num & (num - 1)) 0) printf("the num is a 2^n");else print…

老师如何对付挑事儿的家长?

身为老师&#xff0c;你有没有遇到过这样的家长&#xff1a;孩子在学校里闹点小矛盾&#xff0c;或者作业分数有点争议&#xff0c;他们就气势汹汹地来找你&#xff0c;说你偏心&#xff0c;甚至在其他家长面前说三道四&#xff1f;面对这种爱“挑事”的家长&#xff0c;老师们…