题解 | 链表的奇偶重排
链表的奇偶重排
https://www.nowcoder.com/practice/02bf49ea45cd486daa031614f9bd6fc3
1、解题思路
- 反转后半部分链表:使用快慢指针找到链表的中间节点。反转链表的后半部分。
- 比较前后两部分:将反转后的后半部分与原链表的前半部分逐个节点比较。如果所有节点的值都相同,则链表为回文结构。
- 恢复原链表(可选):如果需要保持原链表结构,可以将后半部分链表反转回来。
2、代码实现
C++
/** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : val(x), next(nullptr) {} * }; */ #include <climits> class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 the head * @return bool布尔型 */ bool isPail(ListNode* head) { // write code here if (head == nullptr || head->next == nullptr) { return true; } // 使用快慢指针找到中间节点 ListNode* slow = head, *fast = head; while (fast->next != nullptr && fast->next->next != nullptr) { slow = slow->next; fast = fast->next->next; } // 反转后半部分链表 ListNode* secondHalf = reverseList(slow->next); ListNode* firstHalf = head; // 比较前后两部分 while (secondHalf) { if (firstHalf->val != secondHalf->val) { return false; } firstHalf = firstHalf->next; secondHalf = secondHalf->next; } return true; } private: // 反转链表函数 ListNode* reverseList(ListNode* head) { ListNode* prev = nullptr, *cur = head; while (cur) { ListNode* next = cur->next; cur->next = prev; prev = cur; cur = next; } return prev; } };
Java
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 the head * @return bool布尔型 */ public boolean isPail (ListNode head) { // write code here if (head == null || head.next == null) { return true; } // 使用快慢指针找到中间节点 ListNode slow = head, fast = head; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } // 反转后半部分链表 ListNode secondHalf = reverseList(slow.next); ListNode firstHalf = head; // 比较前后两部分 while (secondHalf != null) { if (firstHalf.val != secondHalf.val) { return false; } firstHalf = firstHalf.next; secondHalf = secondHalf.next; } return true; } // 反转链表函数 private ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode next = curr.next; curr.next = prev; prev = curr; curr = next; } return prev; } }
Python
# class ListNode: # def __init__(self, x): # self.val = x # self.next = None # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param head ListNode类 the head # @return bool布尔型 # class Solution: def isPail(self, head: ListNode) -> bool: # write code here if not head or not head.next: return True # 使用快慢指针找到中间节点 slow = fast = head while fast.next and fast.next.next: slow = slow.next fast = fast.next.next # 反转后半部分链表 second_half = self.reverseList(slow.next) first_half = head # 比较前后两部分 while second_half: if first_half.val != second_half.val: return False first_half = first_half.next second_half = second_half.next return True # 反转链表函数 def reverseList(self, head: ListNode) -> ListNode: prev = None curr = head while curr: next_node = curr.next curr.next = prev prev = curr curr = next_node return prev
3、复杂度分析
- 时间复杂度:O(n)。
- 空间复杂度:O(1)。