链表(1)

1,005 阅读1分钟

Day 03 翻转链表

1、翻转链表

  • while循环
    class Solution {
        public ListNode reverseList(ListNode head) {
    	ListNode pre = null;
    	ListNode next = head;
    	while (head != null){
    		next = head.next;
    		head.next = pre;
    		pre = head;
    		head = next;
    	}
    	return pre;
        }
     }
    
  • 递归

    核心在递归翻转newHead向前承接的过程

    class Solution {
        public ListNode reverseList(ListNode head) {
    	if (head == null || head.next == null){
    		return head;
    	}
    	ListNode newHead = reverseList(head.next);
    	head.next.next = head;
    	head.next = null;
    	return newHead;
      }
    }
    

2、翻转前k个链表

  • 递归。第1题的扩展

    需要将head的next指向第k+1个链表

      func reverseK(head *ListNode, k int) *ListNode {
            if head.Next == nil || k == 1 {
                    return head
            }
            last := reverse_K(head.Next, k-1)
            temp := head.Next
            head.Next = temp.Next
            temp.Next = head
            return last
      }
    

3、区间翻转

  • 前k个翻转的扩展

    当left为0,即为翻转前k个

      func reverseBetween(head *ListNode, left int, right int) *ListNode {
            if left == 1 {
                    return reverse_K(head, right)
            }
            head.Next = reverseBetween(head.Next,left - 1,right - 1)
            return head
      }
        func reverse_K(head *ListNode, k int) *ListNode {
            if head.Next == nil || k == 1 {
                    return head
            }
            last := reverse_K(head.Next, k-1)
            temp := head.Next
            head.Next = temp.Next
            temp.Next = head
            return last
      }
    
  • for循环解法
    class Solution {
    /**
     * 1、找到左侧节点
     * 2、对区间内的节点进行翻转,记录区间外的节点头
     * 3、连接1 2 3
     * @param head 头结点
     * @param left 左侧
     * @param right 右侧
     * @return 翻转结果
     */
    public ListNode reverseBetween(ListNode head, int left, int right) {
    	if (head == null || left >= right ){
    		return head;
    	}
    	ListNode node = new ListNode(-1);
    	node.next = head;
    	head = node;
    	for (int i = 1; i < left; i++) {
    		head = head.next;
    	}
    	ListNode pre = head;
    	ListNode curr = head.next;
    	ListNode tail = curr;
    	ListNode next = null;
    	ListNode tempPre = tail;
    
    	for (int i = left; i <= right; i++) {
    		next = curr.next; //345  45  5
    		curr.next = tempPre;
    		tempPre = curr;//32
    		curr = next;//45
    	}
    	pre.next = tempPre;//1  432
    	tail.next = next;//5
    
    	return node.next;
    }
    

} ```