LeetCode-234. 迴文鏈表(C語言)

數據結構複習到了鏈表,順便也把這個題解了
leet上最快的解題是把鏈表的內容複製到數組,然後從數組兩端比較

我的解法只使用了鏈表,所以會慢於數組解法

思路:

  1. 使用快慢指針來確定鏈表的中間位置,慢指針每次走一步,快指針走兩步
    如果是ABCD偶數個元素情況,慢指針最後會指向B;快指針由於初始化時提前移動了一位(即初始化時慢指針指向A,快指針指向B),所以快指針最後指向D
    如果是ABCDE奇數個情況,慢指針恰好指向中點C,快指針指向E
  2. 將慢指針之後的鏈表斷開(或者視爲兩個鏈表),然後對後半鏈表進行逆反操作
  3. 對兩部分鏈表從頭開始比較,如果有不同則不是迴文鏈表。
  4. 對後半部分鏈表再次進行逆操作,恢復原順序,再將前半鏈表和後半鏈表鏈接起來,恢復初始狀態。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverse_list(struct ListNode *list)
{//abc -> cba
    struct ListNode *tail = list;
    struct ListNode *ptr = list;
    struct ListNode *fast;
    while(tail->next != NULL)
        tail = tail->next;
    while(ptr != tail)
    {
        fast = ptr->next;
        ptr->next = tail->next;
        tail->next = ptr;
        ptr = fast;
    }
    return tail;
}
bool processing(struct ListNode *list,const int length)
{
    if(list == NULL)
        return false;
    
    bool re = true;
    struct ListNode *slow = list;
    struct ListNode *fast = list;
    if((length & 1) == 0)
        fast = fast->next;//提前走一步 爲了找到tail
    while (fast->next != NULL)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    struct ListNode *middle_left = slow;
    slow = slow->next; //中後的第一個位置
    struct ListNode *new_head = reverse_list(slow);
    slow = new_head;
    fast = list;
    while (slow != NULL)
    {
        if (slow->val != fast->val)
        {
            re = false;
            break;
        }
        slow = slow->next;
        fast = fast->next;
    }
    //恢復list
    new_head = reverse_list(new_head);
    middle_left->next = new_head;
    return re;
}
bool isPalindrome(struct ListNode* head) {
    struct ListNode* ptr = head;
    int length=0;
    while(ptr!=NULL)
    {
        ++length;
        ptr = ptr->next;
    }
    if(length<=1)
        return true;
    return processing(head,length);
    
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章