【Java-数据布局】Java 链外貌试题下 “末了一公里”:解决复杂链表题目的 ...

打印 上一主题 下一主题

主题 867|帖子 867|积分 2601


我的个人主页
我的专栏Java-数据布局,希望能帮助到各人!!!点赞❤ 收藏❤


   引言:
Java链表,看似简朴的链式布局,却蕴含着诸多有趣的特性与奥秘,等待我们去发掘。它就像一个神秘的宝藏迷宫,每一个特性都是隐蔽在迷宫深处的珍贵宝藏。链表的环,犹如迷宫中的循环通道,一旦进入,便大概陷入无尽的循环;链表节点的唯一性与重复性,仿佛迷宫中的岔路,有的道路独一无二,有的却似曾相识;而链表的长度变革,又犹如迷宫的动态扩展与收缩。在接下来的题目中,你将化身为勇敢的探险家,深入链表特性的迷宫,运用你的编程智慧,解开一个个谜题。通过检测链表的环、分析节点的重复性以及精准计算链表长度,你将徐徐揭开链表神秘的面纱,明白数据布局背后的奥妙逻辑。
  6.编写代码,以给定值x为基准将链表分割成两部分,所有⼩于x的结点排在⼤于或等于x的结点之前—链表分割

   题目视图:

  题目详解代码:
  1. // 定义链表节点类
  2. class ListNode {
  3.     int val;
  4.     ListNode next;
  5.     ListNode(int x) {
  6.         val = x;
  7.         next = null;
  8.     }
  9. }
  10. public class PartitionList {
  11.     public ListNode partition(ListNode pHead, int x) {
  12.         // 创建两个虚拟头节点,分别用于存储小于 x 和大于等于 x 的节点
  13.         ListNode smallDummy = new ListNode(0);
  14.         ListNode largeDummy = new ListNode(0);
  15.         // 分别指向两个新链表的当前节点
  16.         ListNode smallTail = smallDummy;
  17.         ListNode largeTail = largeDummy;
  18.         // 遍历原链表
  19.         ListNode current = pHead;
  20.         while (current != null) {
  21.             if (current.val < x) {
  22.                 // 如果当前节点的值小于 x,将其连接到 small 链表的尾部
  23.                 smallTail.next = current;
  24.                 smallTail = smallTail.next;
  25.             } else {
  26.                 // 如果当前节点的值大于等于 x,将其连接到 large 链表的尾部
  27.                 largeTail.next = current;
  28.                 largeTail = largeTail.next;
  29.             }
  30.             // 移动到下一个节点
  31.             current = current.next;
  32.         }
  33.         // 断开 large 链表的尾部,防止出现循环
  34.         largeTail.next = null;
  35.         // 将 small 链表和 large 链表连接起来
  36.         smallTail.next = largeDummy.next;
  37.         // 返回重新排列后的链表的头节点
  38.         return smallDummy.next;
  39.     }
  40.     public static void main(String[] args) {
  41.         // 创建测试链表 1 -> 4 -> 3 -> 2 -> 5 -> 2
  42.         ListNode head = new ListNode(1);
  43.         head.next = new ListNode(4);
  44.         head.next.next = new ListNode(3);
  45.         head.next.next.next = new ListNode(2);
  46.         head.next.next.next.next = new ListNode(5);
  47.         head.next.next.next.next.next = new ListNode(2);
  48.         PartitionList solution = new PartitionList();
  49.         int x = 3;
  50.         // 调用 partition 方法进行重新排列
  51.         ListNode newHead = solution.partition(head, x);
  52.         // 打印重新排列后的链表
  53.         ListNode current = newHead;
  54.         while (current != null) {
  55.             System.out.print(current.val + " ");
  56.             current = current.next;
  57.         }
  58.     }
  59. }
复制代码

7.链表的回⽂布局。题目链接

   题目视图:

  题目详解代码:
  1. package Demo1_28;
  2. /**
  3. * Created with IntelliJ IDEA.
  4. * Description:
  5. * User:Lenovo
  6. * Date:2025-01-28
  7. * Time:20:04
  8. */
  9. // 定义链表节点类
  10. class ListNode {
  11.     int val;
  12.     ListNode next;
  13.     ListNode(int x) {
  14.         val = x;
  15.         next = null;
  16.     }
  17. }
  18. public class PalindromeLinkedList {
  19.     public boolean isPalindrome(ListNode A) {
  20.         if (A == null || A.next == null) {
  21.             return true;
  22.         }
  23.         // 步骤 1:找到链表的中间节点
  24.         ListNode slow = A;
  25.         ListNode fast = A;
  26.         while (fast.next != null && fast.next.next != null) {
  27.             slow = slow.next;
  28.             fast = fast.next.next;
  29.         }
  30.         // 步骤 2:反转链表的后半部分
  31.         ListNode secondHalf = reverseList(slow.next);
  32.         // 步骤 3:比较链表的前半部分和反转后的后半部分
  33.         ListNode p1 = A;
  34.         ListNode p2 = secondHalf;
  35.         boolean result = true;
  36.         while (result && p2 != null) {
  37.             if (p1.val != p2.val) {
  38.                 result = false;
  39.             }
  40.             p1 = p1.next;
  41.             p2 = p2.next;
  42.         }
  43.         // 步骤 4:恢复链表的原始结构
  44.         slow.next = reverseList(secondHalf);
  45.         return result;
  46.     }
  47.     // 反转链表的方法
  48.     private ListNode reverseList(ListNode head) {
  49.         ListNode prev = null;
  50.         ListNode curr = head;
  51.         while (curr != null) {
  52.             ListNode nextTemp = curr.next;
  53.             curr.next = prev;
  54.             prev = curr;
  55.             curr = nextTemp;
  56.         }
  57.         return prev;
  58.     }
  59.     public static void main(String[] args) {
  60.         // 创建测试链表 1 -> 2 -> 2 -> 1
  61.         ListNode head = new ListNode(1);
  62.         head.next = new ListNode(2);
  63.         head.next.next = new ListNode(2);
  64.         head.next.next.next = new ListNode(1);
  65.         PalindromeLinkedList solution = new PalindromeLinkedList();
  66.         // 调用 isPalindrome 方法判断链表是否为回文结构
  67.         boolean isPalindrome = solution.isPalindrome(head);
  68.         System.out.println(isPalindrome);
  69.     }
  70. }
复制代码

8.输⼊两个链表,找出它们的第⼀个公共结点。—题目链接

   题目视图:

  题目详解代码:
  1. package Demo1_28;
  2. /**
  3. * Created with IntelliJ IDEA.
  4. * Description:
  5. * User:Lenovo
  6. * Date:2025-01-28
  7. * Time:20:08
  8. */
  9. // 定义链表节点类
  10. class ListNode {
  11.     int val;
  12.     ListNode next;
  13.     // 构造函数,用于初始化节点的值
  14.     ListNode(int x) {
  15.         val = x;
  16.         next = null;
  17.     }
  18. }
  19. public class IntersectionOfTwoLinkedLists {
  20.     // 查找两个链表相交的起始节点的方法
  21.     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  22.         // 如果其中一个链表为空,直接返回 null
  23.         if (headA == null || headB == null) {
  24.             return null;
  25.         }
  26.         // 初始化两个指针分别指向两个链表的头节点
  27.         ListNode pA = headA;
  28.         ListNode pB = headB;
  29.         // 当两个指针不相等时,继续循环
  30.         while (pA != pB) {
  31.             // 如果 pA 到达链表 A 的末尾,将其指向链表 B 的头节点
  32.             pA = pA == null ? headB : pA.next;
  33.             // 如果 pB 到达链表 B 的末尾,将其指向链表 A 的头节点
  34.             pB = pB == null ? headA : pB.next;
  35.         }
  36.         // 返回相交节点,如果不相交则返回 null
  37.         return pA;
  38.     }
  39.     public static void main(String[] args) {
  40.         // 创建示例链表
  41.         // 链表 A: 1 -> 2 -> 3 -> 6 -> 7
  42.         ListNode headA = new ListNode(1);
  43.         headA.next = new ListNode(2);
  44.         headA.next.next = new ListNode(3);
  45.         // 链表 B: 4 -> 5 -> 6 -> 7
  46.         ListNode headB = new ListNode(4);
  47.         headB.next = new ListNode(5);
  48.         // 创建相交部分
  49.         ListNode intersection = new ListNode(6);
  50.         intersection.next = new ListNode(7);
  51.         // 连接链表 A 和相交部分
  52.         headA.next.next.next = intersection;
  53.         // 连接链表 B 和相交部分
  54.         headB.next.next = intersection;
  55.         // 创建 IntersectionOfTwoLinkedLists 类的实例
  56.         IntersectionOfTwoLinkedLists solution = new IntersectionOfTwoLinkedLists();
  57.         // 调用 getIntersectionNode 方法查找相交节点
  58.         ListNode result = solution.getIntersectionNode(headA, headB);
  59.         if (result != null) {
  60.             System.out.println("相交节点的值为: " + result.val);
  61.         } else {
  62.             System.out.println("两个链表不相交");
  63.         }
  64.     }
  65. }
复制代码

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

   题目视图:

  题目详解代码:
  1. // 定义链表节点类
  2. class ListNode {
  3.     int val;
  4.     ListNode next;
  5.     // 构造函数,用于初始化节点的值
  6.     ListNode(int x) {
  7.         val = x;
  8.         next = null;
  9.     }
  10. }
  11. public class LinkedListCycle {
  12.     // 判断链表是否有环的方法
  13.     public boolean hasCycle(ListNode head) {
  14.         // 如果链表为空或者只有一个节点,肯定没有环
  15.         if (head == null || head.next == null) {
  16.             return false;
  17.         }
  18.         // 慢指针,初始指向头节点,每次移动一步
  19.         ListNode slow = head;
  20.         // 快指针,初始指向头节点的下一个节点,每次移动两步
  21.         ListNode fast = head.next;
  22.         // 当慢指针和快指针不相等时,继续循环
  23.         while (slow != fast) {
  24.             // 如果快指针到达链表末尾或者快指针的下一个节点是末尾,说明没有环
  25.             if (fast == null || fast.next == null) {
  26.                 return false;
  27.             }
  28.             // 慢指针移动一步
  29.             slow = slow.next;
  30.             // 快指针移动两步
  31.             fast = fast.next.next;
  32.         }
  33.         // 如果跳出循环,说明慢指针和快指针相遇了,链表有环
  34.         return true;
  35.     }
  36.     public static void main(String[] args) {
  37.         // 创建有环链表 1 -> 2 -> 3 -> 4 -> 2(环从节点 2 开始)
  38.         ListNode node1 = new ListNode(1);
  39.         ListNode node2 = new ListNode(2);
  40.         ListNode node3 = new ListNode(3);
  41.         ListNode node4 = new ListNode(4);
  42.         // 构建链表连接关系
  43.         node1.next = node2;
  44.         node2.next = node3;
  45.         node3.next = node4;
  46.         // 形成环
  47.         node4.next = node2;
  48.         // 创建 LinkedListCycle 类的实例
  49.         LinkedListCycle solution = new LinkedListCycle();
  50.         // 调用 hasCycle 方法判断链表是否有环
  51.         boolean result = solution.hasCycle(node1);
  52.         System.out.println("链表是否有环: " + result);
  53.         // 创建无环链表 1 -> 2 -> 3 -> 4
  54.         ListNode nodeA = new ListNode(1);
  55.         ListNode nodeB = new ListNode(2);
  56.         ListNode nodeC = new ListNode(3);
  57.         ListNode nodeD = new ListNode(4);
  58.         // 构建无环链表连接关系
  59.         nodeA.next = nodeB;
  60.         nodeB.next = nodeC;
  61.         nodeC.next = nodeD;
  62.         // 再次调用 hasCycle 方法判断无环链表是否有环
  63.         result = solution.hasCycle(nodeA);
  64.         System.out.println("链表是否有环: " + result);
  65.     }
  66. }
复制代码

10.给定⼀个链表,返回链表开始⼊环的第⼀个节点。 如果链表⽆环,则返回 NULL

—题目链接
   题目视图:

  题目详解代码:
  1. package Demo1_28;
  2. /**
  3. * Created with IntelliJ IDEA.
  4. * Description:
  5. * User:Lenovo
  6. * Date:2025-01-28
  7. * Time:20:15
  8. */
  9. // 定义链表节点类
  10. class ListNode {
  11.     int val;
  12.     ListNode next;
  13.     ListNode(int x) {
  14.         val = x;
  15.         next = null;
  16.     }
  17. }
  18. public class LinkedListCycleII {
  19.     public ListNode detectCycle(ListNode head) {
  20.         // 如果链表为空或只有一个节点,肯定没有环
  21.         if (head == null || head.next == null) {
  22.             return null;
  23.         }
  24.         // 慢指针,初始指向头节点,每次移动一步
  25.         ListNode slow = head;
  26.         // 快指针,初始指向头节点,每次移动两步
  27.         ListNode fast = head;
  28.         boolean hasCycle = false;
  29.         // 寻找是否有环
  30.         while (fast != null && fast.next != null) {
  31.             slow = slow.next;
  32.             fast = fast.next.next;
  33.             // 快慢指针相遇,说明有环
  34.             if (slow == fast) {
  35.                 hasCycle = true;
  36.                 break;
  37.             }
  38.         }
  39.         // 如果没有环,返回 null
  40.         if (!hasCycle) {
  41.             return null;
  42.         }
  43.         // 慢指针重新指向头节点
  44.         slow = head;
  45.         // 快慢指针都以每次一步的速度移动,再次相遇的节点就是环的入口节点
  46.         while (slow != fast) {
  47.             slow = slow.next;
  48.             fast = fast.next;
  49.         }
  50.         return slow;
  51.     }
  52.     public static void main(String[] args) {
  53.         // 创建有环链表 1 -> 2 -> 3 -> 4 -> 2(环从节点 2 开始)
  54.         ListNode node1 = new ListNode(1);
  55.         ListNode node2 = new ListNode(2);
  56.         ListNode node3 = new ListNode(3);
  57.         ListNode node4 = new ListNode(4);
  58.         // 构建链表连接关系
  59.         node1.next = node2;
  60.         node2.next = node3;
  61.         node3.next = node4;
  62.         // 形成环
  63.         node4.next = node2;
  64.         // 创建 LinkedListCycleII 类的实例
  65.         LinkedListCycleII solution = new LinkedListCycleII();
  66.         // 调用 detectCycle 方法找到环的入口节点
  67.         ListNode result = solution.detectCycle(node1);
  68.         if (result != null) {
  69.             System.out.println("环的入口节点的值为: " + result.val);
  70.         } else {
  71.             System.out.println("链表中没有环");
  72.         }
  73.         // 创建无环链表 1 -> 2 -> 3 -> 4
  74.         ListNode nodeA = new ListNode(1);
  75.         ListNode nodeB = new ListNode(2);
  76.         ListNode nodeC = new ListNode(3);
  77.         ListNode nodeD = new ListNode(4);
  78.         // 构建无环链表连接关系
  79.         nodeA.next = nodeB;
  80.         nodeB.next = nodeC;
  81.         nodeC.next = nodeD;
  82.         // 再次调用 detectCycle 方法判断无环链表是否有环
  83.         result = solution.detectCycle(nodeA);
  84.         if (result != null) {
  85.             System.out.println("环的入口节点的值为: " + result.val);
  86.         } else {
  87.             System.out.println("链表中没有环");
  88.         }
  89.     }
  90. }
复制代码

所有的链表题目就分享到着了继续加油❤

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

飞不高

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表