算法題-按照左右半區的方式重新組合單鏈表


[編程題]按照左右半區的方式重新組合單鏈表

時間限制:1秒 空間限制:32768K

給定一個單鏈表的頭部節點head,鏈表長度為N。 如果N為偶數,那么前N/2個節點算作左半區,后N/2個節點算作右半區; 如果N為奇數,那么前N/2個節點算作左半區,后N/2+1個節點算作右半區; 左半區從左到右依次記為L1->L2->…,右半區從左到右依次記為R1->R2->…。請將單鏈表調整成L1->R1->L2->R2->…的樣子。 例如: 1->2->3->4 調整后:1->3->2->4 1->2->3->4->5 調整后:1->3->2->4->5 要求:如果鏈表長度為N,時間復雜度請達到O(N),額外空間復雜度請達到O(1)

思路:
創建一個新Vector,先將整個鏈表push_back如心得Vector中,同時將其按下標分成左右兩個鏈表,從前到后逐個判斷”鏈表”(實則已是在Vector中操作)從頭到尾的第奇數還是偶數位,Vector的奇數位插入原鏈表右側元素,偶數為插入原鏈表左側元素,直到鏈表(Vector)結束;

    /* * 按照左右半區的方式重新組合單鏈表 * 輸入:一個單鏈表的頭節點head * 將鏈表調整成題目要求的樣子 */

class Solution {
public:

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

    void relocateList(struct ListNode* pHead) {
        ListNode* Pointer = pHead;
        vector<int> Vector;
        while (Pointer != NULL) {
            Vector.push_back(Pointer->val);
            Pointer = Pointer->next;
        }
        Pointer = pHead;
        int IndexOfVector = 0;
        int IndexOfLeft = 0;
        int IndexOfRight = Vector.size() / 2;
        while (IndexOfVector<Vector.size()-1 && Pointer != NULL) {
            if (IndexOfVector % 2 == 0) {//鏈表偶數位(包括0)
                Pointer->val = Vector[IndexOfLeft++];
                Pointer = Pointer->next;
            }
            else if (IndexOfVector % 2 != 0) {//鏈表奇數位
                Pointer->val = Vector[IndexOfRight++];
                Pointer = Pointer->next;
            }
            ++IndexOfVector;
        }
    }
};

解法2

class Solution {
public:
    void relocateList(struct ListNode* head) {
        ListNode* p = head ;
        int length = 0 ;
        while ( p != NULL ) {
            ++ length ;
            p = p -> next ;
        }

        vector<int> vec ;
        p = head ;
        for ( int i = 0; i < length; ++ i ) {
            vec.push_back( p->val ) ;
            p = p->next ;
        }

        p = head ;
        int left_cur = 0 ;
        int right_cur = length / 2 ;
        int index = 0 ;
        while( index < vec.size() - 1 && p != NULL ) {
            if ( index % 2 == 0 ) {
                p->val = vec[left_cur] ;
                ++ left_cur ;
            }
            else {
                p->val = vec[right_cur] ;
                ++ right_cur ;
            }
            p = p->next ;
            ++ index ;
        }
    }
};

【基本思路】

  先遍歷一遍找到左半區的最后一個節點,然后將鏈表分成左右兩部分,在按照題目要求重新合並即可。

  如何找到左半區的最后一個節點?
  
  例如:1 -> 2,mid為1;
  1 -> 2 -> 3,mid為2;
  1 -> 2 -> 3 -> 4,mid為2;
  1 -> 2 -> 3 -> 4 -> 5,mid為3;
  1 -> 2 -> 3 -> 4 -> 5 -> 6,mid為3;

  也就是說,從長度為2開始,長度每增加2,mid就往后移動一個節點。

Python實現

#python3.5
def reCombination(head):
    if head == None or head.next == None:
        return head
    mid = head
    right = head.next
    while right.next != None and right.next.next != None:
        mid = mid.next
        right = right.next.next
    right = mid.next
    mid.next = None
    cur = head
    while cur.next != None:
        rightNext = right.next
        right.next = cur.next
        cur.next = right
        cur = right.next
        right = rightNext
    cur.next = right
    return head

Python解法參考


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: