Reverse Linked List

Reverse Linked List I II

链表的转置,很容易考到的题目。

1. Reverse Linked List I

思路分析:
将链表转置,分为递归实现和非递归实现。

1.1 递归实现

递归实现代码简单,很有趣。
思路:首先反转从第二个结点到最后一个结点的链表,然后再将头结点放到已反转链表的最后,函数返回新链表的头结点。

class Solution {
public:
    ListNode *reverse(ListNode *head) {
    if (head == 0 || head->next == 0)
         return head;
    ListNode *reversehead, *second;
    second = head->next;
    head->next = 0;
    reversehead = reverse(second);
    /* second已经成转置的部分链表的最后一个结点 */
    second->next = head;
    return reversehead;
    }
};

1.2 非递归实现

思路:
头插法,从第二个开始,一个一个地插入,插入操作需要3个指针,pre、cur、next,pre指向需要插入位置的前驱,cur指向当前需要头插的结点,next指向需要插入的下一个结点为了保持链表不丢。

class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @return: The new head of reversed linked list.
     */
    ListNode *reverse(ListNode *head) {
        // write your code here
        if (head == 0 || head->next == 0)
            return head;
        ListNode *pre, *cur, *next;
        pre = new ListNode(0);
        pre->next = head;
        cur = head->next;
        /* 转置后head是最后一个结点,所以先置head->next=0 */
        head->next = 0;
        while (cur) {
            next = cur->next;
            cur->next = pre->next;
            pre->next = cur;
            cur = next;
        }
        return pre->next;
    }
};

代码好长

1.3 非递归实现

ListNode *reverse(ListNode *head) {
    ListNode *pre, *cur;
    pre = 0;
    cur = head;
    while (cur) {
        ListNode *pnext = cur->next;
        cur->next = pre;
        pre = cur;
        cur = pnext;
    }
    return pre;
}

简单明了。

2. Reverse Linked List II

Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.

2.1 我的实现

链表题目:
1. 注意需要几个指针,插入操作,需要保存插入结点的前一个结点的指针,注意头结点是否需要特殊处理;
2. 这个题目,转置一个区间内的结点,分析清楚需要,需要两个指针front、cur分别指向这个区间的开始和结束,同时pre、next指向插入的位置和下一个要插入的结点,转置一般都是头插法,为了统一处理第一个结点一般会添加头结点。
思路分析:
我的实现链表不断,需要4个指针,自认为比较容易理解。

ListNode *reverseBetween(ListNode *head, int m, int n) {
        // write your code here
        if (0 == head || 0 == head->next)
            return head;
        ListNode *pre, *cur, *pnext, *newhead, *front;
        pre = new ListNode(0);
        pre->next = head;
        newhead = pre;
        cur = head;
        n -= m;
        while (-- m) {
            pre = cur;
            cur = cur->next;
        }
        /* front和cur分别指向区间内开始和结束的位置 */
        front = cur;
        while (n) {
            pnext = cur->next;
            cur->next = pnext->next;
            pnext->next = front;
            pre->next = pnext;
            front = pnext;
            -- n;
        }
        return newhead->next;
    }

因为题目给出1<=m<=n<=len,所以我没有再加判断,应该是加上判断会更好。2.2解法都添加。

2.2 参考别人的解法

思路分析:
把需要转置的区间转置完成后,头和尾分别连接OK,也挺容易理解。

public class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        if (m >= n || head == null) {
            return head;
        }

        ListNode dummy = new ListNode(0);
        dummy.next = head;
        head = dummy;

        for (int i = 1; i < m; i++) {
            if (head == null) {
                return null;
            }
            head = head.next;
        }

        ListNode premNode = head;
        ListNode mNode = head.next;
        ListNode nNode = mNode, postnNode = mNode.next;
        for (int i = m; i < n; i++) {
            if (postnNode == null) {
                return null;
            }
            ListNode temp = postnNode.next;
            postnNode.next = nNode;
            nNode = postnNode;
            postnNode = temp;
        }
        mNode.next = postnNode;
        premNode.next = nNode;

        return dummy.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值