面试经典150题【51-60】

文章目录

  • 面试经典150题【51-60】
    • 71.简化路径
    • 155.最小栈
    • 150.逆波兰表达式求值
    • 224.基本计算器
    • 141.环形链表
    • 2.两数相加
    • 21.合并两个有序链表
    • 138.随机链表的复制
    • 19.删除链表的倒数第N个节点
    • 82.删除链表中的重复元素II

面试经典150题【51-60】

71.简化路径

在这里插入图片描述
先用split(“/”)分开。然后依次放入栈中。如果遇到两个点,说明要返回上一级,要弹出一次栈。用栈的话函数是push和pop。注意pop之前要判断栈是否为空。最后按栈弹出顺序,逆序拼接即可。

public class LC71 {
    @Test
    public void test(){
        System.out.println(simplifyPath("/../"));

    }
    public String simplifyPath(String path) {
        Deque<String> stack=new LinkedList<>();
        String[] strings = path.split("/");
        for(String str:strings){
            if("..".equals(str)){
                if(!stack.isEmpty()){
                    stack.pop();
                }
            }else if(!str.isEmpty() && !str.equals("/")){
                stack.push(str);
            }
        }
        String res = "";
        for (String d : stack)
            res = "/" + d + res;
        return res.isEmpty() ? "/" : res;

    }
}

155.最小栈

在这里插入图片描述
主要就是获取最小元素,我一开始想的是再搞个优先队列。后来看答案,发现两个栈也可以。
比如我在栈一塞入[ 1,2,3] ,那我在最小栈就塞入 [ 1,1,1] ,然后弹出的时候一起弹出就行。主要是在push的时候取个Math.min(x,minStack.top)

150.逆波兰表达式求值

在这里插入图片描述
用一个栈,数据往里面放。如果遇到运算符,则从栈中取出两个数据进行运算,然后再放回栈中。
最后栈里只剩下一个元素。即为答案。

224.基本计算器

在这里插入图片描述
每一个数字,都应该根据他前面的符号数量和种类,判断是乘以+1还是-1; 新建一个符号的栈,有左括号就push进去一个,有右括号就pop出来一个。stack 记录的是截止到这个左括号为止,前面的正负号应该为谁。
1+(2-(3+4))
先把ops=1; 碰到+号,ops=1; 碰到(,栈里为 1
碰到- ops=-1 又碰到左括号 栈里 1 -1
碰到右括号,弹出-1, 栈里 1

public class LC224 {
    @Test
    public void test(){
        System.out.println(calculate("(1+(4+5+2)-3)+(6+8)"));
    }
    public int calculate(String s){
        Deque<Integer> stack=new LinkedList<>();
        int i=0,ops=1,ans=0;
        stack.push(1);
        while(i<s.length()){
            if(' ' == (s.charAt(i))){
                i++;
                continue;
            }else if('+'==(s.charAt(i))){
                ops = stack.peek();
                i++;

            }else if('-' == (s.charAt(i))){
                ops=-stack.peek();
                i++;

            }else if('(' == (s.charAt(i))){
                stack.push(ops);
                i++;

            }else if(')' == (s.charAt(i))){
                stack.pop();
                i++;

            }else{
                //一个数字
                int temp=0;
                while(i<s.length() && Character.isDigit(s.charAt(i))){
                    temp=temp*10+s.charAt(i)-'0';
                    i++;
                }
                ans += ops * temp;

            }
        }
        return ans;
    }
}

141.环形链表

最经典的快慢指针。非常经典的一道题。不想赘述了。必会

2.两数相加

在这里插入图片描述
这个数字是逆序的,也就是说。2和5才是个位数。

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode pre=new ListNode();
        ListNode cur=pre;
        int carry=0;
        while(l1 !=null || l2 !=null){
            //只要有一个不为空就应该继续遍历,为空就是为0
            int val1=l1==null ? 0 : l1.val;
            int val2=l2==null ? 0 : l2.val;
            int sum=val1+val2+carry;
            cur.next=new ListNode(sum%10);
            //注意指针要移动
            cur=cur.next;
            carry=sum/10;
            //注意指针要移动
            if(l1 != null) l1=l1.next;
            if(l2 != null) l2=l2.next;

        }
        //最后一位的进位是否存在。
        if(carry == 1) cur.next=new ListNode(1);
        return pre.next;
    }

21.合并两个有序链表

在这里插入图片描述
从原则上来说应该是双指针遍历两个链表。但是也可以用递归去简化这个流程。
如果list1.val比较小的话,list1.next= merge( list1.next , list2)

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1==null) return list2;
        if(list2==null) return list1;
        if(list1.val < list2.val){
            list1.next = mergeTwoLists(list1.next,list2);
            return list1;
        }else{
            list2.next=mergeTwoLists(list2.next,list1);
            return list2;
        }

    }
}

138.随机链表的复制

我们用哈希表来解决这个问题
首先创建一个哈希表,再遍历原链表,遍历的同时再不断创建新节点
我们将原节点作为key,新节点作为value放入哈希表中
在这里插入图片描述
第二步我们再遍历原链表,这次我们要将新链表的next和random指针给设置上

从上图中我们可以发现,原节点和新节点是一一对应的关系,所以

map.get(原节点),得到的就是对应的新节点
map.get(原节点.next),得到的就是对应的新节点.next
map.get(原节点.random),得到的就是对应的新节点.random
所以,我们只需要再次遍历原链表,然后设置:
新节点.next -> map.get(原节点.next)
新节点.random -> map.get(原节点.random)
这样新链表的next和random都被串联起来了
最后,我们然后map.get(head),也就是对应的新链表的头节点,就可以解决此问题了。

class Solution {
    public Node copyRandomList(Node head) {
        if(head==null) {
            return null;
        }
        //创建一个哈希表,key是原节点,value是新节点
        Map<Node,Node> map = new HashMap<Node,Node>();
        Node p = head;
        //将原节点和新节点放入哈希表中
        while(p!=null) {
            Node newNode = new Node(p.val);
            map.put(p,newNode);
            p = p.next;
        }
        p = head;
        //遍历原链表,设置新节点的next和random
        while(p!=null) {
            Node newNode = map.get(p);
            //p是原节点,map.get(p)是对应的新节点,p.next是原节点的下一个
            //map.get(p.next)是原节点下一个对应的新节点
            if(p.next!=null) {
                newNode.next = map.get(p.next);
            }
            //p.random是原节点随机指向
            //map.get(p.random)是原节点随机指向  对应的新节点 
            if(p.random!=null) {
                newNode.random = map.get(p.random);
            }
            p = p.next;
        }
        //返回头结点,即原节点对应的value(新节点)
        return map.get(head);
    }
}

当然还有一种方法是将其变为 1->1’-> 2 -> 2’
然后再将其拆开为1’ -> 2’
不过拆开的函数有点小复杂:

 //第三步,将两个链表分离
        while(p!=null) {
            cur.next = p.next;
            cur = cur.next;
            p.next = cur.next;
            p = p.next;
        }

19.删除链表的倒数第N个节点

先用快慢指针找到倒数第N个,然后直接 slow.next = slow.next.next即可

82.删除链表中的重复元素II

在这里插入图片描述
比如对于1->2->2->2->3要变为1->3
设置虚拟节点0,当有两个数相同的时候,cur.next.val == cur.next.next.val
记录x=cur.next.val; 如果cur.next.val==x,则直接换下一个指针 cur.next=cur.next.next;
这样才能把第一个2也给消除掉。

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
         if (head == null) {
            return head;
        }
        
        ListNode dummy = new ListNode(0, head);

        ListNode cur = dummy;
        while (cur.next != null && cur.next.next != null) {
            if (cur.next.val == cur.next.next.val) {
                int x = cur.next.val;
                while (cur.next != null && cur.next.val == x) {
                    cur.next = cur.next.next;
                }
            } else {
                cur = cur.next;
            }
        }

        return dummy.next;

    }
}

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

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

相关文章

Flutter混合栈管理方案对比

1.Google官方&#xff08;多引擎方案&#xff09; Google官方建议的方式是多引擎方案&#xff0c;即每次使用一个新的FlutterEngine来渲染Widget树&#xff0c;存在的主要问题是每个引擎都要有比较大的内存等资源消耗&#xff0c;虽然Flutter 2.0之后的FlutterEngineGroup通过在…

如何选择O2OA(翱途)开发平台的部署架构?

概述 O2OA(翱途)开发平台[下称O2OA开发平台或者O2OA]支持公有云&#xff0c;私有云和混合云部署&#xff0c;也支持复杂的网络结构下的分布式部署。本篇主要介绍O2OA(翱途)开发平台支持的部署环境以及常用的集群部署架构。 软硬件环境说明 支持的云化平台&#xff1a; 华为云…

【算法】二叉搜索树的插入、删除、转换操作

1 二叉搜索树的插入操作 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能…

卷积神经网络(CNN)原理与实现

卷积神经网络(CNN) 卷积神经网络原理卷积神经网络的数学推导卷积层反向传播算法数学推导卷积层实现代码 卷积神经网络(CNN) 卷积神经网络原理 卷积神经网络是一种用于图像、语音、自然语言等数据的深度学习模型&#xff0c;其核心思想是使用卷积操作提取输入数据的特征&…

【开源项目】经典开源项目数字孪生智慧医院

飞渡科技数字孪生医院管理平台&#xff0c;融合数字孪生、物联网IOT、无线定位等技术&#xff0c;提供病房管理、医疗管理、照明管理、停车场管理等应用&#xff0c;同时结合完善的安防系统&#xff0c;立体化、全覆盖的视频监控体系&#xff0c;实现医院数字化卓越运营以及精细…

汇编语言程序设计实验二

实验目的和要求 继续学习使用DEBUG程序的各种命令。利用DEBUG学习了解计算机取指令、执行指令的工作过程。 掌握8086/8088基本指令的使用方法和功能。 实验环境 DOSBox 0.74 实验内容与过程 1&#xff0e; 按照下列给定步骤完成求累加和程序: 程序: MOV BX,1000MOV C…

MBR10200FCT-ASEMI适配开关电源MBR10200FCT

编辑&#xff1a;ll MBR10200FCT-ASEMI适配开关电源MBR10200FCT 型号&#xff1a;MBR10200FCT 品牌&#xff1a;ASEMI 封装&#xff1a;ITO-220AB 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;10A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xf…

BUUCTF---[极客大挑战 2019]Upload1

1.题目描述 2.点开链接&#xff0c;需要上传文件&#xff0c;要求是image&#xff0c;上传文件后缀为jpg的一句话木马&#xff0c;发现被检测到了 3.换另一个木马试试 GIF89a? <script language"php">eval($_REQUEST[1])</script> 发现可以上传成功 4…

(C语言)sizeof和strlen的对比(详解)

sizeof和strlen的对⽐&#xff08;详解&#xff09; 1. sizeof sizeof是用来计算变量所占内存空间大小的&#xff0c; 单位是字节&#xff0c;如果操作数是类型的话&#xff0c;计算的是用类型创建的变量所占空间的大小。 sizeof 只关注占用内存空间的大小 &#xff0c;不在乎内…

GitLab EE 企业版破解

在当今数字化时代&#xff0c;软件开发与团队协作已经成为现代企业不可或缺的一部分。而在这个过程中&#xff0c;版本控制、协作和持续集成等工具的运用变得至关重要。GitLab作为一个领先的、完整的DevOps平台&#xff0c;为团队提供了一个集成的解决方案&#xff0c;使得软件…

【Leetcode每日一题】DP35 二维前缀和(难度⭐⭐)(26)

1. 题目解析 题目链接&#xff1a;DP35 【模板】二维前缀和 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给二维区间数组元素和返回即可。 2. 算法原理 和上题了类似的方法&#xff0c;使用dp数组来保存[1…

科普【1】:web3.0初探,不懂技术也能看懂。

Hi&#xff0c;我是贝格前端工场&#xff0c;本期来科普一下web3这个概念&#xff0c;力争讲的浅显易懂。 一、什么是web3及其特征 Web3是指第三代互联网&#xff0c;也被称为分布式互联网或区块链互联网。它是对传统互联网的一种进化和扩展&#xff0c;旨在提供更加去中心化、…

为什么中小APP开发者要选择聚合SDK广告变现服务?

广告变现听起来容易&#xff0c;但要在不影响用户体验的情况下&#xff0c;把变现收益做到最大化&#xff0c;其实非常复杂。 对于处于行业腰部和尾部的中小APP来说&#xff0c;团队资源有限&#xff0c;要将所有的资源集中在投入到核心业务竞争力上——扩大用户规模和活跃度上…

如何测试代理IP是否可用?

目录 一、了解代理IP基础知识 二、为什么需要测试代理IP的可用性&#xff1f; 三、测试代理IP的可用性方法 使用Ping命令测试代理IP的连通性 使用curl或wget测试代理IP的可用性 编写代码测试代理IP的可用性 四、案例分析 五、总结与建议 在数字时代的今天&#xff0c;代…

.net 日志

一、Log4net 1、log4net写入文本 1、nuget引入log4net、Microsoft.Extensions.Logging.Log4Net.AspNetCore这2个 2、引入配置文件,可以直接去官网(log4net官网配置文件)复制下来,放到项目目录下面,设置成始终复制,因为这个文件最终要到我们项目运行目录下面去 3、要在pr…

3月4日工作记录

周末总结 周末花6.5k的4060ti主机到家了&#xff0c;配好了和女朋友一起玩了两天帕鲁&#xff0c;真好玩&#xff01; 玩完开始上班&#xff01; 今天&#xff0c;上午先看三篇paper&#xff0c;然后下午继续1日计划的工作 文章阅读 文章一&#xff1a;SciGLM: Training Sc…

STL——stack

目录 stack stack都有哪些接口 模拟实现一个stack stack 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配器被实现的&#xff0c;容器适配器即…

【一起学习Arcade】(5):属性规则实例_计算规则

属性规则可改善地理数据库数据集的编辑体验并提高数据完整性。 这些规则均为用户定义的规则&#xff0c;可用于自动填充属性、在编辑操作期间限制无效编辑&#xff0c;以及对现有要素执行质量保证检查。 属性规则分为3类&#xff1a;计算、约束和验证。 这一篇介绍计算规则&…

HOOPS Communicator对3D大模型轻量化加载与渲染的4种解决方案

今天给大家介绍一些关于3D Web轻量化引擎HOOPS Commuicator的关键概念&#xff0c;这些概念可以帮您在HOOPS Communicator流缓存服务器之上更好地构建您自己的模型流服务器。如果您是有大型数据集&#xff0c;那么&#xff0c;使用流缓存服务器可以极大地帮助您最大限度地减少内…

PostgreSQL10.21与PostGIS3.2.3安装文档

背景&#xff1a; 公司需要在一个服务器上装一个pg数据库&#xff0c;要求和其余服务器版本尽量保持一致&#xff0c;临时拉我装一下 特别注意&#xff1a; 需要注意的地方就是因为postgresql数据库是一个空间库&#xff0c;gis行业很多都会使用这个数据库&#xff0c;我们安…