面试经典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 {@Testpublic 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 {@Testpublic 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){//只要有一个不为空就应该继续遍历,为空就是为0int 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和randomwhile(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.hqwc.cn/news/509019.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【软件设计师】通俗易懂的去了解算法的时间复杂度

&#x1f413; 时间复杂度 常用排序的时间复杂度 时间频度 算法需要花费的时间&#xff0c;和它语句执行的次数是成正比的&#xff0c;所以会把一个算法种语句执行次数称为语句频度和时间频度、记作T(n)。 定义 时间复杂度就是找到一个无限接近时间频度T(n)同数量级的函数&am…

基于springboot+vue实现校企合作项目管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现校企合作项目管理系统演示 摘要 这是一个计算机的时代&#xff0c;在计算机应用非常广泛的时代中&#xff0c;用计算机来完成对信息的处理有着非常好的使用效果。特别是针对学校而言亦是如此&#xff0c;通过在学校中的信息化建设&#xff0c;能够很好的提升…

S3---FPGA-A7板级电源硬件实战

视频链接 FPGA-A7板级电源硬件实战01_哔哩哔哩_bilibili FPGA-A7板级电源硬件实战 1、基于A7 板级的系统框图 2、基于A7 板级的电源设计细则 2.1、A7 FPGA功耗评估 Artix-7 FPGA电源有VCCINT, VCCBRAM, VCCAUX, VCCO, VMGTAVCC和VMGTAVTT。 2.1.1、A7 FPGA电源管脚 2.1.2…

http 协议深入介绍

一&#xff0c;http 相关概念 &#xff08;一&#xff09;关键名词 1&#xff0c;互联网 是网络的网络&#xff0c;是所有类型网络的母集 2&#xff0c;因特网 世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上&#xff0c;大家把连接在因特网上的计算机都成…

Matlab|基于Logistic函数负荷需求响应

目录 1 基于Logistic函数的负荷转移率模型 2 程序示例 3 效果图 4 下载链接 负荷需求响应模型种类较多&#xff0c;有电价型和激励型等类型&#xff0c;本次和大家分享一个基于Logistic函数的负荷转移率模型&#xff0c;该模型属于电价型&#xff0c;由于该方法使用的较少&a…

AGM CPLD (AGRV2K )的时钟(外部时钟和片上内部振荡器)

AGM CPLD &#xff08;AGRV2K &#xff09;的时钟(外部时钟和片上内部振荡器) 外部晶振 与 内部振荡器&#xff1a; mcu 和 cpld 联合编程时&#xff0c; 整颗芯片需要一颗外部晶振。 &#xff08;芯片有内部振荡器&#xff0c; 但误差较大&#xff0c; 校准后 5%以内误差&…

二维码门楼牌管理系统技术服务:制作详解

文章目录 前言一、二维码门楼牌制作技术要求二、二维码门楼牌管理系统的优势与应用 前言 随着信息化时代的到来&#xff0c;二维码技术已广泛应用于各个领域。在城市管理中&#xff0c;二维码门楼牌管理系统的应用为城市管理带来了极大的便利。本文将详细探讨二维码门楼牌管理…

STM32CubeMX实战教程: TIM6、TIM7 - 基本定时器

基本定时器的作用 基本定时器&#xff0c;主要用于实现定时和计数功能。作用包括&#xff1a; 定时功能&#xff1a;可以产生周期性的中断&#xff0c;用于实现定时任务。例如&#xff0c;可以设置一个定时器每隔一定时间&#xff08;如1秒&#xff09;产生一次中断&#xff0…

【Android移动开发】helloworld项目文件剖析

本文讨论了一个Android应用的Gradle项目的各个方面。涵盖了Gradle的启动脚本&#xff0c;项目的配置文件&#xff08;如build.gradle和gradle.properties&#xff09;&#xff0c;以及应用的源代码和资源文件。具体内容包括了项目结构、Gradle插件的配置、AndroidManifest.xml文…

mysql5.7配置主从

原理&#xff1a; MySQL主从复制的工作原理如下:1. 主服务器产生Binlog日志当主服务器的数据库发生数据修改操作时,如INSERT、UPDATE、DELETE语句执行,主服务器会记录这些操作的日志信息到二进制日志文件中。2. 从服务器读取Binlog日志 从服务器会向主服务器发送请求,主服务器把…

护眼灯真能护眼吗?保护视力必入的五款护眼台灯

自从入手了护眼台灯后&#xff0c;我深深感受到了它使用的便捷性和舒适性。它不仅为学习和工作环境提供了充足的光线&#xff0c;确保能在明亮的环境中专注于任务&#xff0c;而且其光线柔和&#xff0c;极大地减轻了对眼睛的压力。同时&#xff0c;护眼台灯的防蓝光措施做得相…

uniapp开发android原生插件

一、下载原生开发SDK Android 离线SDK - 正式版 | uni小程序SDK (dcloud.net.cn)、 https://nativesupport.dcloud.net.cn/AppDocs/download/android.html 将开发uniappa原生android的插件解压到ben本地目录&#xff0c;目录结构如下&#xff1a; 接下就可以使用 UniPlugin-Hel…