LeetCode 234/9/125:回文链表,回文数,验证回文串

这篇博客探讨了LeetCode中关于回文的三个问题:234题回文链表,通过双指针法、翻转链表或使用栈来解决;9题回文数,通过转化成字符串或翻转一半整数来判断;125题验证回文串,使用双指针法结合C++库函数isalnum和tolower处理非字母数字和大小写问题。
摘要由CSDN通过智能技术生成

 234:回文链表

将链表存入数组再判断:

Python有语法糖,不需要双指针法,直接就可以翻转比较。 

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        array = []
        currNode = head
        while currNode is not None:
            array.append(currNode.val)
            currNode = currNode.next
        return array == array[::-1]

C++采用双指针法,也很简单直接。 

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        vector<int> vals;
        ListNode *cur = head;
        while(cur) {
            vals.push_back(cur->val);
            cur = cur->next;
        }

        int n = vals.size();
        int i = 0, j = n-1;
        while(i <= j) {
            if(vals[i] == vals[j]) {
                i++;
                j--;
            }
            else {
                return false;
            }
        }
        return true;
    }
};

利用栈的方法来比较:

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        stack<int> s;
        ListNode *cur = head;
        while(cur) {
            s.push(cur->val);
            cur = cur->next;
        }

        cur = head;
        while(!s.empty()) {
            if(s.top() == cur->val) {
                cur = cur->next;
                s.pop();
            }
            else {
                return false;
            }
        }
        return true;
    }
};

性能最优的方法:时间O(n),空间O(1),快慢指针找到链表中点,只翻转一半的链表,再进行比较。

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next) return true;

        ListNode *slow = head, *fast = head; //快慢指针,确保只翻转了一半的链表
        ListNode *pre = nullptr, *cur = slow;
        while(fast && fast->next) {
            cur = slow;
            slow = slow->next;
            fast = fast->next->next;

            cur->next = pre;
            pre = cur;
        }
        //奇偶分开讨论
        if(fast) { //链表偶数个节点时,fast会为null
            slow = slow->next; //奇数个节点,需要跳过中间节点比较两边的节点
        }

        while(cur && slow) {
            if(cur->val != slow->val) return false;
            cur = cur->next;
            slow = slow->next;
        }
        return true;
    }
};

9. 回文数

一种方法是把 int 变量转化为 string 然后用双指针法从两端开始比较,另外一种是翻转 int 但是担心会溢出,仔细分析可知只翻转一半即可,但要注意int的位数为奇数时翻转的部分会多一位,所以return部分要稍加改动。

class Solution {
public:
    bool isPalindrome(int x) {
        if(x < 0 || ((x % 10 == 0) && (x != 0)) ) return false;
        
        int y = 0;
        while(x > y) {
            y = y * 10 + x % 10;
            x /= 10;
        }

        return (x == y) || (y/10 == x);
    }
};

125. 验证回文串

采用双指针法,从两端往中间走,非字母数字问题和大小写问题,用两个C++库函数就可以。

isalnum(char c):判断字符变量c是否为字母或数字,若是则返回非零,否则返回零。
tolower(char c):把字母字符转换成小写,非字母字符不做出处理。

class Solution {
public:
    bool isPalindrome(string s) {
        if(s.size() <= 1) return true;

        int i = 0, j = s.size() - 1;
        while (i<j) {
            while(i<j && !isalnum(s[i])) {
                i++;
            }
            while(i<j && !isalnum(s[j])) {
                j--;
            }
            if(tolower(s[i]) != tolower(s[j])) {
                return false;
            }
            i++;
            j--; //漏掉这两行会导致第一次比较完就陷入死循环
        }
        return true;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值