链表相关算法题详解

1、(LeetCode21)合并两个有序链表

  链接:https://leetcode.cn/problems/merge-two-sorted-lists/

  题目:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

  思路:这道题可以用递归来做,首先判断两个链表的首节点哪个比较小,小的作为新节点,然后剩余的部分重复这个函数实现。

  代码实现:

1 class Solution { 2 public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 3 if(l1 == null) return l2; 4 if(l2 == null) return l1; 5 if(l1.val < l2.val){ 6 l1.next = mergeTwoLists(l1.next,l2); 7 return l1; 8 } 9 l2.next = mergeTwoLists(l1,l2.next); 10 return l2; 11 } 12 }

2、(LeetCode83)删除排序链表中的重复元素

  链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-list/

  题目:给定一个已排序的链表的头head, 删除所有重复的元素,使每个元素只出现一次 。返回已排序的链表。

  思路:同样地用递归,如果首节点和第二个节点的值相等,那么就返回第二个节点,剩余的部分操作相同。

  代码实现:

1 class Solution { 2 public ListNode deleteDuplicates(ListNode head) { 3 if(head == null || head.next == null) return head; 4 head.next = deleteDuplicates(head.next); 5 return head.val == head.next.val?head.next:head; 6 } 7 }

3、(LeetCode141)环形链表

  链接:https://leetcode.cn/problems/linked-list-cycle/

  题目:给你一个链表的头节点head,判断链表中是否有环。

  思路:定义两个指针,一个快指针,一个慢指针,快指针一次移动两个节点,慢指针一次移动一个节点,如果存在环的话,那么这两个指针肯定会相遇,如果不存在环的话,那么就会走到结尾的null。

  代码实现:

1 public class Solution { 2 public boolean hasCycle(ListNode head) { 3 if(head == null) return false; 4 ListNode slowPtr = head,fastPtr = head; 5 while(fastPtr.next != null && fastPtr.next.next != null){ 6 slowPtr = slowPtr.next; 7 fastPtr = fastPtr.next.next; 8 if(slowPtr == fastPtr){ 9 return true; 10 } 11 } 12 return false; 13 } 14 }

4、(LeetCode142)环形链表II

  链接:https://leetcode.cn/problems/linked-list-cycle-ii/

  题目:给定一个链表的头节点head,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

  思路:这道题算是上道题的升级版了,只需要将上道题的代码简单做下改动就可以了。首先开始的时候添加一个标志位来判断链表是否有环,当快慢指针相遇时,标志位置为true,代表存在环。当环存在时,慢指针指向头结点,快指针速度和慢指针相同,那么两指针相遇的位置就是环的起始位置。可能有的人理解不了为什么两指针相遇就是起始位置,这里我跳出题目,举个例子就懂了。

   像左图那样在一个环形链表定义两个指针,一个快指针一个慢指针,在一个位置出发,那么肯定还会在这个位置相遇,如果说我要是像右图那样,起点提前了n个节点,那么相遇的位置也会离上次相遇的位置距离n个节点,这个时候我要是把慢指针放到开始的位置上,并且快指针的速度也和慢指针一样,那么他们肯定会在环的入环位置相遇。

  代码实现:

1 public class Solution { 2 public ListNode detectCycle(ListNode head) { 3 if(head == null) return null; 4 ListNode slowPtr = head,fastPtr = head; 5 boolean loopExists = false; 6 while(fastPtr.next != null && fastPtr.next.next != null){ 7 slowPtr = slowPtr.next; 8 fastPtr = fastPtr.next.next; 9 if(slowPtr == fastPtr){ 10 loopExists = true; 11 break; 12 } 13 } 14 if(loopExists){ 15 slowPtr = head; 16 while(slowPtr != fastPtr){ 17 fastPtr = fastPtr.next; 18 slowPtr = slowPtr.next; 19 } 20 return slowPtr; 21 } 22 return null; 23 } 24 }

5、(LeetCode160)相交链表

  链接:https://leetcode.cn/problems/intersection-of-two-linked-lists/comments/

  题目:给你两个单链表的头节点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回null。

  思路:分别在两个表头定义两个指针,对链表进行遍历,遍历结束移向另一个表的表头,直到两交点相等。看过代码的话,可能会有这样一个疑问,如果两个链表长度一样并且还无交点,会不会死循环?当然这个也是不会的,因为遍历到最后,两个指针都指向了null,这时候就会把null返回出去,也是符合条件的。

  代码实现:

1 public class Solution { 2 public ListNode getIntersectionNode(ListNode headA, ListNode headB) { 3 if(headA == null || headB == null){ 4 return null; 5 } 6 ListNode pA = headA,pB = headB; 7 while(pA != pB){ 8 pA = pA == null ? headB : pA.next; 9 pB = pB == null ? headA : pB.next; 10 } 11 return pA; 12 } 13 }

6、(LeetCode206)反转链表

  链接:https://leetcode.cn/problems/reverse-linked-list/

  题目:给你单链表的头节点head,请你反转链表,并返回反转后的链表。

  思路:这道题只需要循环将当前节点的next指向前一个节点就OK了,注意在第一个节点之前加null.

  代码实现:

1 class Solution { 2 public ListNode reverseList(ListNode head) { 3 ListNode preNode = null; 4 ListNode curr = head; 5 while(curr != null){ 6 ListNode next = curr.next; 7 curr.next = preNode; 8 preNode = curr; 9 curr = next; 10 } 11 return preNode; 12 } 13 }

7、(LeetCode234)回文链表

  链接:https://leetcode.cn/problems/palindrome-linked-list/

  题目:给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

  思路:先定义一个栈,将链表的节点值存入到栈中,存好了之后,用pop()方法弹出末项来和头结点的值进行比较,若不相等,则返回false,若遍历完成,返回true。

  代码实现:

1 class Solution { 2 public boolean isPalindrome(ListNode head) { 3 Stack<Integer> stack = new Stack<Integer>(); 4 ListNode cur = head; 5 while(cur != null){ 6 stack.push(cur.val); 7 cur = cur.next; 8 } 9 while(head != null){ 10 if(stack.pop() != head.val){ 11 return false; 12 } 13 head = head.next; 14 } 15 return true; 16 } 17 }

 


__EOF__

本文作者向阳最优秀
本文链接https://www.cnblogs.com/xiangyangboke/p/16388699.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   小向阳最优秀  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示

喜欢请打赏

扫描二维码打赏

支付宝打赏