回文链表(leetcode)

我自己第一个写的代码:

bool isPalindrome(struct ListNode* head){
    struct ListNode* tail = NULL;
    struct ListNode* pos = NULL;
    if( head->next == NULL)
    {
        return true;
    }
    while( 1 )
    {
        if(  head->next == NULL || (head->next->next == NULL && head->val==head->next->val) )
        {
            return true;
        }
        for( tail = head ; tail->next->next != NULL ; tail = tail->next);
        if( head->val != tail->next->val)
        return false;
        if(  head->next == NULL || head->next->next == NULL )
        {
            return true;
        }
        pos = head;
        head = head->next;
        tail->next = NULL;
        pos->next = NULL;
    }
}

1               2                  3                 2               1 

比较第一个数和最后一个数,注意不要把指针放在最后,因为要将最后的链点删除,则考虑倒数第二个链点,并且if条件判断要放在两处,为了防止对空指针解引用

但此时时间复杂度过高O(n)  循环内的代码均要执行一遍,导致超时

算法:首先将链表分成两节,将后一节的链表翻转,在一一比较

1             2             3             3                2            1       

1            2               3   ||   3        2           1

1       2           3          ||      1           2         3

struct ListNode* rollback( struct ListNode* head )
{
    struct ListNode* pos = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode* p1 = head;
    struct ListNode* p2 = head->next;
    while( p2 != NULL )
    {
        p1->next = p2->next;
        p2->next = pos->next;
        pos->next = p2;
        p2 = p1->next;
    }
    return pos->next;
}
        
struct ListNode* get_listnode(struct ListNode* head)
{
    struct ListNode* fast = head->next;
    struct ListNode* slow = head;
    struct ListNode* arr = NULL;
    while( fast != NULL && fast->next != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    arr = slow->next;
    slow->next = NULL;
    return arr;
}

bool isPalindrome(struct ListNode* head){

    struct ListNode* mid_listnode = NULL;
    struct ListNode* tail = NULL;
    if( head == NULL )
    {
        return true;
    }
    mid_listnode = get_listnode(head);
    tail = rollback(mid_listnode);
    while( tail != NULL )
    {

        if( head->val != tail->val )
        {
            return false;
        }
        tail = tail->next;
        head = head->next;
    } 这里的比较执行n/2次

    return true;
}

时间复杂度分析:rollback函数内的语句执行n/2次

                             get_listnode函数内的语句执行n/2次

                           T =   O(n)

空间复杂度:O(1)

你可能感兴趣的:(链表,leetcode,linux)