链表 题

文章目录

    • 找出链表中类中点的位置
    • 判断该链表是否为回文结构
    • 将单向链表按某值划分成左边小、中间相等、右边大的形式
    • 给定一个有next指针和rand指针的Node 组成的无环单链表头节点,实现一个函数完成链表的复制,返回新链表的头节点
    • 给定两个可能有环也可能无环的单链表,头节点head1和head2 实现一个函数,如果两个链表相交,返回相交的第一个结点,不相交返回null
    • 能不能不给单链表的头节点,只给想删除的结点,就能做到在链表上把这个点删掉?

找出链表中类中点的位置

快慢指针

1)输入链表头节点,奇数长度返回中点,偶数长度返回上中点
2)输入链表头节点,奇数长度返回中点,偶数长度返回下中点
3)输入链表头节点,奇数长度返回中点前一个,偶数长度返回上中点前一个
4)输入链表头节点,奇数长度返回中点前一个,偶数长度返回下中点前一个

public class Code01_LinkedListMid { public static class Node {public int value;public Node next;public Node(int v) {value = v;}}// 1)public static Node midOrUpMidNode(Node head) {if (head == null || head.next == null || head.next.next == null) {return head;}// 链表有3个点或以上Node slow = head.next;Node fast = head.next.next;while (fast.next != null && fast.next.next != null) {slow = slow.next;fast = fast.next.next;}return slow;}// 2)public static Node midOrDownMidNode(Node head) {if (head == null || head.next == null) {return head;}Node slow = head.next;Node fast = head.next;while (fast.next != null && fast.next.next != null) {slow = slow.next;fast = fast.next.next;}return slow;}// 3)public static Node midOrUpMidPreNode(Node head) {if (head == null || head.next == null || head.next.next == null) {return null;}Node slow = head;Node fast = head.next.next;while (fast.next != null && fast.next.next != null) {slow = slow.next;fast = fast.next.next;}return slow;}// 4)public static Node midOrDownMidPreNode(Node head) {if (head == null || head.next == null) {return null;}if (head.next.next == null) {return head;}Node slow = head;Node fast = head.next;while (fast.next != null && fast.next.next != null) {slow = slow.next;fast = fast.next.next;}return slow;}// 1)public static Node right1(Node head) {if (head == null) {return null;}Node cur = head;ArrayList<Node> arr = new ArrayList<>();while (cur != null) {arr.add(cur);cur = cur.next;}return arr.get((arr.size() - 1) / 2);}// 2)public static Node right2(Node head) {if (head == null) {return null;}Node cur = head;ArrayList<Node> arr = new ArrayList<>();while (cur != null) {arr.add(cur);cur = cur.next;}return arr.get(arr.size() / 2);}// 3)public static Node right3(Node head) {if (head == null || head.next == null || head.next.next == null) {return null;}Node cur = head;ArrayList<Node> arr = new ArrayList<>();while (cur != null) {arr.add(cur);cur = cur.next;}return arr.get((arr.size() - 3) / 2);}// 4)public static Node right4(Node head) {if (head == null || head.next == null) {return null;}Node cur = head;ArrayList<Node> arr = new ArrayList<>();while (cur != null) {arr.add(cur);cur = cur.next;}return arr.get((arr.size() - 2) / 2);}
}

判断该链表是否为回文结构

给定一个单链表的头节点head,请判断该链表是否为回文结构。
1)栈方法特别简单 (笔试用)
2)改原链表的方法就需要注意边界了 (面试用)

public class Code02_IsPalindromeList {public static class Node {public int value;public Node next;public Node(int data) {this.value = data;}}// need n extra space 栈public static boolean isPalindrome1(Node head) {Stack<Node> stack = new Stack<Node>();Node cur = head;while (cur != null) {stack.push(cur);cur = cur.next;}while (head != null) {if (head.value != stack.pop().value) {return false;}head = head.next;}return true;}// need n/2 extra space 栈 快慢指针public static boolean isPalindrome2(Node head) {if (head == null || head.next == null) {return true;}Node right = head.next;Node cur = head;while (cur.next != null && cur.next.next != null) {right = right.next;cur = cur.next.next;}Stack<Node> stack = new Stack<Node>();while (right != null) {stack.push(right);right = right.next;}while (!stack.isEmpty()) {if (head.value != stack.pop().value) {return false;}head = head.next;}return true;}// need O(1) extra space 反转链表public static boolean isPalindrome3(Node head) {if (head == null || head.next == null) {return true;}Node n1 = head;Node n2 = head;while (n2.next != null && n2.next.next != null) { // find mid noden1 = n1.next; // n1 -> midn2 = n2.next.next; // n2 -> end}// n1 中点n2 = n1.next; // n2 -> right part first noden1.next = null; // mid.next -> nullNode n3 = null;while (n2 != null) { // right part convertn3 = n2.next; // n3 -> save next noden2.next = n1; // next of right node convertn1 = n2; // n1 moven2 = n3; // n2 move}n3 = n1; // n3 -> save last noden2 = head;// n2 -> left first nodeboolean res = true;while (n1 != null && n2 != null) { // check palindromeif (n1.value != n2.value) {res = false;break;}n1 = n1.next; // left to midn2 = n2.next; // right to mid}n1 = n3.next;n3.next = null;while (n1 != null) { // recover listn2 = n1.next;n1.next = n3;n3 = n1;n1 = n2;}return res;}
}

将单向链表按某值划分成左边小、中间相等、右边大的形式

  1. 把链表放入数组里,在数组上做partition (笔试用)
  2. 分成小、中、大三部分,再把各个部分之间串起来(面试用)(有稳定性)
public class Code03_SmallerEqualBigger {public static class Node {public int value;public Node next;public Node(int data) {this.value = data;}}public static Node listPartition1(Node head, int pivot) {if (head == null) {return head;}Node cur = head;int i = 0;while (cur != null) {i++;cur = cur.next;}Node[] nodeArr = new Node[i];i = 0;cur = head;for (i = 0; i != nodeArr.length; i++) {nodeArr[i] = cur;cur = cur.next;}arrPartition(nodeArr, pivot);for (i = 1; i != nodeArr.length; i++) {nodeArr[i - 1].next = nodeArr[i];}nodeArr[i - 1].next = null;return nodeArr[0];}public static Node listPartition2(Node head, int pivot) {Node sH = null; // small headNode sT = null; // small tailNode eH = null; // equal headNode eT = null; // equal tailNode mH = null; // big headNode mT = null; // big tailNode next = null; // save next node// every node distributed to three listswhile (head != null) {next = head.next;head.next = null;if (head.value < pivot) {if (sH == null) {sH = head;sT = head;} else {sT.next = head;sT = head;}} else if (head.value == pivot) {if (eH == null) {eH = head;eT = head;} else {eT.next = head;eT = head;}} else {if (mH == null) {mH = head;mT = head;} else {mT.next = head;mT = head;}}head = next;}// 小于区域的尾巴,连等于区域的头,等于区域的尾巴连大于区域的头if (sT != null) { // 如果有小于区域sT.next = eH;eT = eT == null ? sT : eT; // 下一步,谁去连大于区域的头,谁就变成eT}// 下一步,一定是需要用eT 去接 大于区域的头// 有等于区域,eT -> 等于区域的尾结点// 无等于区域,eT -> 小于区域的尾结点// eT 尽量不为空的尾巴节点if (eT != null) { // 如果小于区域和等于区域,不是都没有eT.next = mH;}return sH != null ? sH : (eH != null ? eH : mH);}
}

给定一个有next指针和rand指针的Node 组成的无环单链表头节点,实现一个函数完成链表的复制,返回新链表的头节点

1)使用hashmap*
2)不使用hashmap

https://leetcode.com/problems/copy-list-with-random-pointer/

import java.util.HashMap;
public class CopyListWithRandom {public static class Node {int val;Node next;Node random;public Node(int val) {this.val = val;this.next = null;this.random = null;}}public static Node copyRandomList1(Node head) {// key 老节点// value 新节点HashMap<Node, Node> map = new HashMap<Node, Node>();Node cur = head;while (cur != null) {map.put(cur, new Node(cur.val));cur = cur.next;}cur = head;while (cur != null) {// cur 老// map.get(cur) 新// 新.next ->  cur.next克隆节点找到map.get(cur).next = map.get(cur.next);map.get(cur).random = map.get(cur.random);cur = cur.next;}return map.get(head);}public static Node copyRandomList2(Node head) {if (head == null) {return null;}Node cur = head;Node next = null;// 1 -> 2 -> 3 -> null// 1 -> 1' -> 2 -> 2' -> 3 -> 3'while (cur != null) {next = cur.next;cur.next = new Node(cur.val);cur.next.next = next;cur = next;}cur = head;Node copy = null;// 1 1' 2 2' 3 3'// 依次设置 1' 2' 3' random指针while (cur != null) {next = cur.next.next;copy = cur.next;copy.random = cur.random != null ? cur.random.next : null;cur = next;}Node res = head.next;cur = head;// 老 新 混在一起,next方向上,random正确// next方向上,把新老链表分离while (cur != null) {next = cur.next.next;copy = cur.next;cur.next = next;copy.next = next != null ? next.next : null;cur = next;}return res;}}

给定两个可能有环也可能无环的单链表,头节点head1和head2 实现一个函数,如果两个链表相交,返回相交的第一个结点,不相交返回null

(包含三类面试题的综合题)(除了以下做法,还可以使用hashSet更加简单的实现)
1)找到链表第一个入环节点,如果无环,返回null
2)如果两个链表都无环,返回第一个相交节点,如果不想交,返回null
3)两个有环链表,返回第一个相交节点,如果不想交返回null

public class FindFirstIntersectNode {public static class Node {public int value;public Node next;public Node(int data) {this.value = data;}}public static Node getIntersectNode(Node head1, Node head2) {if (head1 == null || head2 == null) {return null;}Node loop1 = getLoopNode(head1);Node loop2 = getLoopNode(head2);if (loop1 == null && loop2 == null) {return noLoop(head1, head2);}if (loop1 != null && loop2 != null) {return bothLoop(head1, loop1, head2, loop2);}return null;}// 找到链表第一个入环节点,如果无环,返回nullpublic static Node getLoopNode(Node head) {if (head == null || head.next == null || head.next.next == null) {return null;}// n1 慢  n2 快Node slow = head.next; // n1 -> slowNode fast = head.next.next; // n2 -> fastwhile (slow != fast) {if (fast.next == null || fast.next.next == null) {return null;}fast = fast.next.next;slow = slow.next;}// slow fast  相遇fast = head; // n2 -> walk again from headwhile (slow != fast) {slow = slow.next;fast = fast.next;}return slow;}// 如果两个链表都无环,返回第一个相交节点,如果不想交,返回nullpublic static Node noLoop(Node head1, Node head2) {if (head1 == null || head2 == null) {return null;}Node cur1 = head1;Node cur2 = head2;int n = 0;while (cur1.next != null) {n++;cur1 = cur1.next;}while (cur2.next != null) {n--;cur2 = cur2.next;}if (cur1 != cur2) {return null;}// n  :  链表1长度减去链表2长度的值cur1 = n > 0 ? head1 : head2; // 谁长,谁的头变成cur1cur2 = cur1 == head1 ? head2 : head1; // 谁短,谁的头变成cur2n = Math.abs(n);while (n != 0) {n--;cur1 = cur1.next;}while (cur1 != cur2) {cur1 = cur1.next;cur2 = cur2.next;}return cur1;}// 两个有环链表,返回第一个相交节点,如果不想交返回nullpublic static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {Node cur1 = null;Node cur2 = null;if (loop1 == loop2) {cur1 = head1;cur2 = head2;int n = 0;while (cur1 != loop1) {n++;cur1 = cur1.next;}while (cur2 != loop2) {n--;cur2 = cur2.next;}cur1 = n > 0 ? head1 : head2;cur2 = cur1 == head1 ? head2 : head1;n = Math.abs(n);while (n != 0) {n--;cur1 = cur1.next;}while (cur1 != cur2) {cur1 = cur1.next;cur2 = cur2.next;}return cur1;} else {cur1 = loop1.next;while (cur1 != loop1) {if (cur1 == loop2) {return loop1;}cur1 = cur1.next;}return null;}}
}

能不能不给单链表的头节点,只给想删除的结点,就能做到在链表上把这个点删掉?

不能

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

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

相关文章

.NET Core 2.0迁移技巧之web.config配置文件

大家都知道.NET Core现在不再支持原来的web.config配置文件了&#xff0c;取而代之的是json或xml配置文件。官方推荐的项目配置方式是使用appsettings.json配置文件&#xff0c;这对现有一些重度使用web.cofig配置的项目迁移可能是不可接受的。 但是好消息是&#xff0c;我们是…

jzoj2136-(GDKOI2004)汉诺塔【找规律,模拟】

正题 大意 将汉诺塔的规则改为只能移动到相邻的柱子&#xff0c;然后求有n个圆盘时在第m步时每个盘所在的位置。 解题思路 我们先将3个盘的移动情况推出来&#xff1a;(1,1,1)->(2,1,1)->(3,1,1)->(3,2,1)->(2,2,1)->(1,2,1)->(1,3,1)->(2,3,1)->(3,…

学会它,可以替你写100行 200行 300行……的代码

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。今天&#xff0c;给大家分享一个非常非常使用的小技巧&#xff0c;那就是&#xff1a;“在webstrom中创建一个简单的vue模板”&#xff0c;根据这个方法&#xff0c;你可以任意的创建html模…

Java中随机数的原理,以及使用时的注意点

转载自 Java中随机数的原理&#xff0c;以及使用时的注意点 1 前言 一提到 Java 中的随机数&#xff0c;很多人就会想到 Random&#xff0c;当出现生成随机数这样需求时&#xff0c;大多数人都会选择使用 Random 来生成随机数。Random 类是线程安全的&#xff0c;但其内部使…

MySql 使用 EF Core 2.0 CodeFirst、DbFirst、数据库迁移(Migration)介绍及示例

dotnet core 2.0 发布已经好几天了&#xff0c;期间也把原来 dotnet core 1.1 的 MVC 项目升级到了 2.0&#xff0c;升级过程还是比较顺利的&#xff0c;变动也不是太多。升级的过程中也少不了 Entity Framwork Core 的升级&#xff0c;在这篇文章中主要介绍下 MySql 数据库使用…

下午带着几个同学打了两节课的牌~

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。大赛的项目目前正在火热进行中&#xff0c;靳天宇小组做的是扑克牌的游戏&#xff0c;除了要做大家耳熟能详的“斗地主”之外&#xff0c;另外在我的建议下准备再加两种玩法&#xff0c;一…

Java 0xffffffff隐式类型转换的坑

一、场景复现 项目需求&#xff0c;long的低32位存储ip地址&#xff0c;需要将ip信息展示成为字符串ip。 public static void main(String[] args){long ipLong 0x457145130A1901F6L;String ip longToIp(ipLong&0xffffffff);//取低32位System.out.println(ipLong);Syst…

jzoj2137-(GDKOI2004)城市统计【二维前缀和,bfs】

正题 大意 有n*n的矩阵&#xff0c;有居民区有商业区&#xff0c;每个居民区曼哈顿距离最近的商业区的曼哈顿距离就是那个居民区离商业区的距离。每个格子统计一下以它为中心的2∗r12∗r12∗r12∗r1的矩阵内所有居民区离商业区的距离的和。 解题思路 先bfs计算所有居民离商业…

Razor Page–Asp.Net Core 2.0新功能 Razor Page介绍

Razor Page介绍 前言 上周期待已久的Asp.Net Core 2.0提前发布了&#xff0c;一下子Net圈热闹了起来&#xff0c;2.0带来了很多新的特性和新的功能&#xff0c;其中Razor Page引起我的关注&#xff0c;作为web程序员来说&#xff0c;Asp.Net下的任何web框架都会去特别关注&…

二叉 树

文章目录递归方式 先序、中序、后序 遍历非递归方式 先序、中序、后序 遍历实现二叉树的按层遍历求二叉树的最大宽度二叉树的序列化和反序列化二叉树有 left、right、parent &#xff0c;给这样二叉树的某个结点&#xff0c;返回该节点的后继节点折纸条递归方式 先序、中序、后…

“老师,弃了吧,做个别的……”“笑话,都到这个份上了,怎么能弃掉呢?”...

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。最近项目小组一直在按照原计划做项目&#xff0c;聊天程序&#xff08;高仿版微信&#xff09;已经趋于尾声&#xff0c;做的还可以&#xff0c;剩下的就是美化和慢慢的完善小问题了&#…

IntelliJ IDEA 源值1.5已过时,将在未来所有版本中删除

转载自 IntelliJ IDEA 源值1.5已过时&#xff0c;将在未来所有版本中删除 原因&#xff1a; IDEA默认把项目的源代码版本设置为jdk1.5&#xff0c;目标代码设置为jdk1.5 解决方案&#xff1a; 1修改Maven的Settings.xml文件添加如下内容 <profile><id>jdk-1.8&…

2018/7/16-纪中某C组题【jzoj4024,jzoj4025,jzoj2136,jzoj2137】

题目还好。只是第一题题目错了&#xff0c;第二题真的难 今日分数 Rankperson分数1xxy2302蒟蒻2004xjq1805zyc17017hjq7519hzb2026lw1026lrz10 正题 T1&#xff1a;jzoj4024-石子游戏【SG函数,博弈论】 博客链接&#xff1a;https://blog.csdn.net/mr_wuyongcong/article/d…

.NET Core 2.0迁移技巧之MemoryCache问题修复

对于传统的.NET Framework项目而言&#xff0c;System.Runtime.Caching命名空间是常用的工具了&#xff0c;其中MemoryCache类则常被用于实现内存缓存。 .NET Core 2.0暂时还不支持System.Runtime.Caching dll&#xff0c;这也就意味着MemoryCache相关代码不再起作用了。 但是…

今天干了两件大事!

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。今天干了两件大事。第一件就是为明天的“IT技能大赛”做了充足准备&#xff0c;带着6个班级的7个小组&#xff0c;在报告厅过了一遍&#xff0c;然后安排了两个后台控制同学&#xff0c;主…

JAVA后端面试100 QA之第一篇

转载自 JAVA后端面试100 Q&A之第一篇 1. synchronized和reentrantlock异同 相同点 都实现了多线程同步和内存可见性语义都是可重入锁 不同点 实现机制不同 synchronized通过java对象头锁标记和Monitor对象实现 reentrantlock通过CAS、ASQ&#xff08;AbstractQueuedSy…

P2158,jzoj1709-仪仗队【欧拉函数,数论】

正题 评测记录&#xff1a;https://www.luogu.org/recordnew/lists?uid52918&pidP2158 大意 有n∗nn∗n个点&#xff0c;求从(1,1)(1,1)可以看到多少个点。 解题思路 我们将(1,1)(1,1)当做(0,0)(0,0)&#xff0c;然后所有点往下和后移一步 我们可以发现点距离点(0,0…

asp.net core MVC 过滤器之ExceptionFilter过滤器(一)

简介 异常过滤器&#xff0c;顾名思义&#xff0c;就是当程序发生异常时所使用的过滤器。用于在系统出现未捕获异常时的处理。 实现一个自定义异常过滤器 自定义一个异常过滤器需要实现IExceptionFilter接口 public class HttpGlobalExceptionFilter : IExceptionFilter { …

今天是个特殊的一天,有意义的一天,值得纪念的一天~

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。今天是个特殊的一天&#xff0c;筹划准备两周时间的IT技能大赛终于在报告厅顺利举行&#xff0c;全校6个班级共有7个小组参加本次技能大赛&#xff0c;大家的项目丰富多彩&#xff0c;不但…

Arrays.asList()坑

new ArrayList(Arrays.asList()) 这样可以使用add remove clear方法