数据结构与算法面试程序员

数据结构面试 之 回文单链表 附图解

2017-03-27  本文已影响91人  Linux后端研发工程实践

1.限制与要求

2.思考

回文最初的概念是应用在字符串上的,比如"abccba"和“abcdcba”都是回文字符串。判断是否是回文字符串的算法也很简单,使用两个下标i、j,i从头开始向后遍历,j从尾开始向前遍历,只要i < j就一直遍历,在遍历过程中如果i和j位置上的字符不相同,则该字符串必然不是回文的并立即停止遍历,如果遍历结束后都没遇到不相同的字符,则该字符串是回文的。

3.算法图解

4.代码实现

/*
    21 / 21 test cases passed.
    Status: Accepted
    Runtime: 28 ms
    Desc: 链表操作和思维的综合考察:
        1、对原链表进行拆分成左右两半
        2、对右半部分进行逆序
        3、进行回文判断
 */
#include <iostream>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode * getRight(ListNode * head)
    {
        int len = 1;
        ListNode * right = NULL;
        ListNode * cur = head;
        while (head->next != NULL)
        {
            ++len;
            head = head->next;
        }
        
        if (0 == len % 2) //偶数节点
        {
            len /= 2;
            --len;
            while (len--)
            {
                cur = cur->next;
            }
            right = cur->next; //保存右半链表的起始节点指针
            cur->next = NULL;  //这里断开
        }
        else //奇数节点
        {
            len /= 2;
            --len;
            while (len--)
            {
                cur = cur->next;
            }
            right = cur->next->next; //奇数节点要跳过中间节点
            cur->next->next = NULL;
            cur->next = NULL; //这里断开
        }
        
        return right;
    }
    
    ListNode * reverseList(ListNode * head)
    {
        ListNode * pre = NULL;
        ListNode * temp = head;
        ListNode * cur = head;
        
        while (cur != NULL)
        {
            cur = cur->next;
            temp->next = pre;
            pre = temp;
            temp = cur;
        }
        
        return pre;
    }
    
    bool isPalindrome(ListNode* head) {
        if (NULL == head) return true;
        if (NULL == head->next) return true;
        
        ListNode * left = head;
        ListNode * right = getRight(head); //对链表进行拆分,分成左右两端
        right = reverseList(right); //对右半部分链表进行逆序
        
        //判断是否是回文
        while (left)
        {
            if (left->val != right->val)
            {
                return false;
            }
            left = left->next;
            right = right->next;
        }
        
        return true;
    }
};

5.OJ练习

LeetCode 回文单链表

6.相关题目

单链表逆序

上一篇下一篇

猜你喜欢

热点阅读