LeetCode 回文链表【递归,快慢指针】

编写一个函数,检查输入的链表是否是回文的。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

三种写法。
1.把链表中的数据放到数组里求解。(这种写法不放代码了)

2.递归求解。定一个指向链表起始节点的指针,然后递归遍历链表。在遍历到最后一个节点的时候和起始指针的值尽心比较。然后令指针指向下一位,返回函数返回上一层。
但函数在进行调用的时候会开辟出栈帧,因此空间复杂度仍为O(n)。

3.将链表从中间分为两部分,反转后一部分链表的节点。然后用双指针进行比较。空间复杂度为O(1).

方法2.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *front = NULL;

    bool check(ListNode *cur) {
        if(cur == NULL) return true;
        if(check(cur -> next) == false) return false;
        if(cur -> val != front -> val)  return false;
        front = front -> next;
        return true;
    }

    bool isPalindrome(ListNode* head) {
        front = head;
        return check(head);
    }
};

方法3.

class Solution {
public:

    ListNode *sec = NULL;//存放第二部分链表的头结点。
    ListNode* revList(ListNode *cur) {//反转链表
        if(cur == NULL) return NULL;
        ListNode *tem = revList(cur -> next);
        if(tem != NULL) {
            tem -> next = cur;
        } else {
            sec = cur;
        }
        cur -> next = NULL;
        return cur;
    }

    bool isPalindrome(ListNode* head) {
        ListNode *hair = new ListNode();
        hair -> next = head;
        ListNode *slow = hair, *fast = hair;
        while(true) {//快慢指针将链表分为两部分
            slow = slow -> next;
            if(fast -> next != NULL)    fast = fast -> next;
            else break;
            if(fast -> next != NULL)    fast = fast -> next;
            else break;
        }
        ListNode *cur = revList(slow);
        while(true) {
            if(head == NULL || sec == NULL) break;
            if(head -> val != sec -> val)   return false;
            head = head -> next;
            sec = sec -> next;
        }
        return true;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值