143. Reorder List [LeetCode]

143. Reorder List

 

Given a singly linked list LL0→L1→…→Ln-1→Ln,
reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

You may not modify the values in the list's nodes, only nodes itself may be changed.

Example 1:

Given 1->2->3->4, reorder it to 1->4->2->3.

Example 2:

Given 1->2->3->4->5, reorder it to 1->5->2->4->3.

先对半拆分链表,逆序后面的链表,然后merge成一个链表.

为了便于复习,我把三种链表反转的函数都列出来了.

链表反转见LeetCode:206Reverse Linked List.我整理的相应的解答

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**************************************************************************
 * 
 * 143. [Reorder List](https://leetcode.com/problems/reorder-list/)
 * 
 * You are given the head of a singly linked-list. The list can be represented as:
 * L0 → L1 → … → Ln - 1 → Ln
 * Reorder the list to be on the following form:
 * 
 * L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
 * 
 * You may not modify the values in the list's nodes. Only nodes themselves may be changed.
 * 
 * Example 1:
 * Input: head = [1,2,3,4]
 * Output: [1,4,2,3]
 * 
 * Example 2:
 * Input: head = [1,2,3,4,5]
 * Output: [1,5,2,4,3]
 **************************************************************************/


struct ListNode {
    int val;
    struct ListNode *next;
};

typedef struct ListNode NODE;

int lenOfList(NODE *head) {
    int len = 0;
    while (head) {
        len++;
        head = head->next;
    }
    return len;
}

NODE *reverseList(NODE *head) {
    if (NULL == head || NULL == head->next) 
        return head;
    
    NODE *pre = NULL;
    NODE *cur = head;
    NODE *next= cur->next;
    
    while (cur) {
        cur->next = pre;
        
        pre = cur;
        cur = next;
        if (next)
            next= next->next;
    }
    return pre;
}


NODE *reverse(NODE *head) {
    if (NULL == head || NULL == head->next) 
        return head;
    NODE *p = reverse(head->next);
    head->next->next = head;
    head->next = NULL;
    return p;
}


// l1 head as head
NODE *merger(NODE *l1, NODE *l2) {
    if (NULL == l1) return l2;
    if (NULL == l2) return l1;
    
    NODE *head = l1;
    
    while (l1 && l2) {
        NODE *l1_new = l1->next;
        NODE *l2_new = l2->next;

        l1->next = l2;
        if (l1_new)
            l2->next = l1_new;

        l1 = l1_new;
        l2 = l2_new;
    }

    return head;
}

void reorderList(NODE *head){
    if (NULL == head || NULL == head->next || NULL == head->next->next) 
        return;
#if 1 
/*******************************
 * input    1  2  3  4  5
 *          l1  1  2
 *          l2  5  4  3  <--  3  4  5 (l2)
 * 
 * merger:
 *          1 5 2 4 3 
 *******************************/
#ifdef FORCE
    NODE *l1 = head;
    NODE *l1tail = head;
    NODE *l2 = head;

    int len = lenOfList(head);

    for (int i = 0; i < len / 2 - 1; i++)
        l1tail = l1tail->next;

    l2 = l1tail->next;
    l1tail->next = NULL;

#else 
    NODE *l1 = head;
    NODE *l2 = head;
    NODE *fast = head;
    NODE *prel2 = NULL;

    while (fast && fast->next) {
        prel2 = l2;
        l2 = l2->next;
        fast = fast->next->next;
    }
    prel2->next = NULL;

#endif

#else 

/*******************************
 * if reverse in this way 
 * 
 * input     1  2  3  4  5
 *          l1  1  3  5
 *          l2  4  2      <- 2  4  (l2)
 * 
 * merger:
 *          1 4 3 2 5
 *******************************/

    NODE *l1 = head;
    NODE *l2 = head->next;
    for (NODE *sl1 = l1; sl1; ) {
        NODE *sl1_new = NULL;
        NODE *sl2 = sl1->next;
        if (sl2) {
            sl1_new = sl2->next;
        
            sl1->next = sl1_new;
            if (sl1_new)
                sl2->next = sl1_new->next;
        }
        sl1 = sl1_new;
    }
#endif 

    l2 = reverseList(l2);

    merger(l1, l2);
    return;
}



//
//
/// testCode

void print(NODE *head) {
    printf("len:%d ", lenOfList(head));
    while (head) {
        if (head->next) 
            printf("%d->", head->val);
        else 
            printf("%d", head->val);

        head = head->next;
    }
    printf("\n");
}

NODE *initList(int len, int val) {
    if (len < 1) return NULL;

    NODE *head = (NODE *)calloc(1, sizeof(NODE));
    head->val = val;

    NODE *pos = head;

    for (int i = 1; i < len; i++) {
        NODE *node = (NODE *)calloc(1, sizeof(NODE));
        node->val = val + i;
        pos->next = node;
        pos = node;
    }

    return head;
}


int main() {
    NODE *l1 = initList(4, 1);
    NODE *l2 = initList(5, 5);
    print(l1);
    print(l2);
    reorderList(l1);    
    reorderList(l2);
    print(l1);
    print(l2);

    l1 = reverseList(l1);
    l2 = reverseList(l2);
    print(l1);
    print(l2);

    l1 = merger(l2, l1);
    print(l1);

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luuyiran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值