文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一道新的面试题回文链表你会么?

2024-12-02 18:57

关注

新题来咯,回文链表

回文链表

力扣题目链接:https://leetcode-cn.com/problems/palindrome-linked-list/

请判断一个链表是否为回文链表。

示例 1:

示例 2:

思路

数组模拟

最直接的想法,就是把链表装成数组,然后再判断是否回文。

代码也比较简单。如下:

  1. class Solution { 
  2. public
  3.     bool isPalindrome(ListNode* head) { 
  4.         vector<int> vec; 
  5.         ListNode* cur  = head; 
  6.         while (cur) { 
  7.             vec.push_back(cur->val); 
  8.             cur = cur->next
  9.         } 
  10.         // 比较数组回文 
  11.         for (int i = 0, j = vec.size() - 1; i < j; i++, j--) { 
  12.             if (vec[i] != vec[j]) return false
  13.         } 
  14.         return true
  15.     } 
  16. }; 

上面代码可以在优化,就是先求出链表长度,然后给定vector的初始长度,这样避免vector每次添加节点重新开辟空间

  1. class Solution { 
  2. public
  3.     bool isPalindrome(ListNode* head) { 
  4.  
  5.         ListNode* cur  = head; 
  6.         int length = 0; 
  7.         while (cur) { 
  8.             length++; 
  9.             cur = cur->next
  10.         } 
  11.         vector<int> vec(length, 0); // 给定vector的初始长度,这样避免vector每次添加节点重新开辟空间 
  12.         cur = head; 
  13.         int index = 0; 
  14.         while (cur) { 
  15.             vec[index++] = cur->val; 
  16.             cur = cur->next
  17.         } 
  18.         // 比较数组回文 
  19.         for (int i = 0, j = vec.size() - 1; i < j; i++, j--) { 
  20.             if (vec[i] != vec[j]) return false
  21.         } 
  22.         return true
  23.     } 
  24. }; 

反转后半部分链表

分为如下几步:

如图所示:

代码如下:

  1. class Solution { 
  2. public
  3.     bool isPalindrome(ListNode* head) { 
  4.         if (head == nullptr || head->next == nullptr) return true
  5.         ListNode* slow = head; // 慢指针,找到链表中间分位置,作为分割 
  6.         ListNode* fast = head; 
  7.         ListNode* pre = head; // 记录慢指针的前一个节点,用来分割链表 
  8.         while (fast && fast->next) { 
  9.             pre = slow; 
  10.             slow = slow->next
  11.             fast = fast->next->next
  12.         } 
  13.         pre->next = nullptr; // 分割链表 
  14.  
  15.         ListNode* cur1 = head;  // 前半部分 
  16.         ListNode* cur2 = reverseList(slow); // 反转后半部分,总链表长度如果是奇数,cur2比cur1多一个节点 
  17.  
  18.         // 开始两个链表的比较 
  19.         while (cur1) { 
  20.             if (cur1->val != cur2->val) return false
  21.             cur1 = cur1->next
  22.             cur2 = cur2->next
  23.         } 
  24.         return true
  25.     } 
  26.     // 反转链表 
  27.     ListNode* reverseList(ListNode* head) { 
  28.         ListNode* temp; // 保存cur的下一个节点 
  29.         ListNode* cur = head; 
  30.         ListNode* pre = nullptr; 
  31.         while(cur) { 
  32.             temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->next 
  33.             cur->next = pre; // 翻转操作 
  34.             // 更新pre 和 cur指针 
  35.             pre = cur; 
  36.             cur = temp
  37.         } 
  38.         return pre; 
  39.     } 
  40. }; 

其他语言版本

Java

  1. // 方法一,使用数组 
  2. class Solution { 
  3.     public boolean isPalindrome(ListNode head) { 
  4.         int len = 0; 
  5.         // 统计链表长度 
  6.         ListNode cur = head; 
  7.         while (cur != null) { 
  8.             len++; 
  9.             cur = cur.next
  10.         } 
  11.         cur = head; 
  12.         int[] res = new int[len]; 
  13.         // 将元素加到数组之中 
  14.         for (int i = 0; i < res.length; i++){ 
  15.             res[i] = cur.val; 
  16.             cur = cur.next
  17.         } 
  18.         // 比较回文 
  19.         for (int i = 0, j = len - 1; i < j; i++, j--){ 
  20.             if (res[i] != res[j]){ 
  21.                 return false
  22.             } 
  23.         } 
  24.         return true
  25.     } 
  26.  
  27. // 方法二,快慢指针 
  28. class Solution { 
  29.     public boolean isPalindrome(ListNode head) { 
  30.         // 如果为空或者仅有一个节点,返回true 
  31.         if (head == null && head.next == nullreturn true
  32.         ListNode slow = head; 
  33.         ListNode fast = head; 
  34.         ListNode pre = head; 
  35.         while (fast != null && fast.next != null){ 
  36.             pre = slow;  // 记录slow的前一个结点 
  37.             slow = slow.next
  38.             fast = fast.next.next
  39.         } 
  40.         pre.next = null;  // 分割两个链表 
  41.  
  42.         // 前半部分 
  43.         ListNode cur1 = head; 
  44.         // 后半部分。这里使用了反转链表 
  45.         ListNode cur2 = reverseList(slow); 
  46.  
  47.         while (cur1 != null){ 
  48.             if (cur1.val != cur2.val) return false
  49.  
  50.             // 注意要移动两个结点 
  51.             cur1 = cur1.next
  52.             cur2 = cur2.next
  53.         } 
  54.         return true
  55.     } 
  56.     ListNode reverseList(ListNode head){ 
  57.         // 反转链表 
  58.         ListNode tmp = null
  59.         ListNode pre = null
  60.         while (head != null){ 
  61.             tmp = head.next
  62.             head.next = pre; 
  63.             pre = head; 
  64.             head = tmp; 
  65.         } 
  66.         return pre; 
  67.     } 

 Python

  1. #数组模拟 
  2. class Solution: 
  3.     def isPalindrome(self, head: ListNode) -> bool: 
  4.         length = 0 
  5.         tmp = head 
  6.         while tmp: #求链表长度 
  7.             length += 1 
  8.             tmp = tmp.next 
  9.  
  10.         result = [0] * length 
  11.         tmp = head 
  12.         index = 0 
  13.         while tmp: #链表元素加入数组 
  14.             result[index] = tmp.val 
  15.             index += 1 
  16.             tmp = tmp.next 
  17.  
  18.         i, j = 0, length - 1 
  19.         while i < j: # 判断回文 
  20.             if result[i] != result[j]: 
  21.                 return False 
  22.             i += 1 
  23.             j -= 1 
  24.         return True 
  25.  
  26. #反转后半部分链表 
  27. class Solution: 
  28.     def isPalindrome(self, head: ListNode) -> bool: 
  29.         if head == None or head.next == None: 
  30.             return True 
  31.         slow, fast = head, head 
  32.         while fast and fast.next
  33.             pre = slow 
  34.             slow = slow.next 
  35.             fast = fast.next.next 
  36.  
  37.         pre.next = None # 分割链表 
  38.         cur1 = head # 前半部分 
  39.         cur2 = self.reverseList(slow) # 反转后半部分,总链表长度如果是奇数,cur2比cur1多一个节点 
  40.         while cur1: 
  41.             if cur1.val != cur2.val: 
  42.                 return False 
  43.             cur1 = cur1.next 
  44.             cur2 = cur2.next 
  45.         return True 
  46.  
  47.     def reverseList(self, head: ListNode) -> ListNode: 
  48.         cur = head 
  49.         pre = None 
  50.         while(cur!=None): 
  51.             temp = cur.next # 保存一下cur的下一个节点 
  52.             cur.next = pre # 反转 
  53.             pre = cur 
  54.             cur = temp 
  55.         return pre 

 

来源:代码随想录内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯