天天看點

leetcode19-删除連結清單的倒數第N個節點

  • ​​删除連結清單的倒數第N個節點​​
  • ​​題目描述​​
  • ​​code​​
  • ​​官方答案​​

删除連結清單的倒數第N個節點

題目描述

給定一個連結清單,删除連結清單的倒數第 n 個節點,并且傳回連結清單的頭結點。

示例:

給定一個連結清單: 1->2->3->4->5, 和 n = 2.

當删除了倒數第二個節點後,連結清單變為 1->2->3->5.
說明:      

code

import org.junit.Test;
import java.util.List;

/**
 * 給定一個連結清單,删除連結清單的倒數第 n 個節點,并且傳回連結清單的頭結點。
 * <p>
 * 示例:
 * <p>
 * 給定一個連結清單: 1->2->3->4->5, 和 n = 2.
 * <p>
 * 當删除了倒數第二個節點後,連結清單變為 1->2->3->5.
 * 說明:
 * <p>
 * 給定的 n 保證是有效的。
 * <p>
 * 進階:
 * 你能嘗試使用一趟掃描實作嗎?
 */
public class LeetCode19 {
    @Test
    public void test() {
        Solution s = new Solution();
        ListNode head = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);
        ListNode node5 = new ListNode(5);
        head.next = node2;
//        node2.next = node3;
//        node3.next = node4;
//        node4.next = node5;
        ListNode node = s.removeNthFromEnd(head, 2);

        while(node!= null){
            System.out.println(node.val);
            node= node.next;
        }
    }


    class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    //删除倒數的第n個節點,并傳回頭結點
    //思路: 雙指針,先走n步,然後兩個指針同時走,還需要一個指針,進行連接配接
    //為空/ 超過 / 正常 /頭結點/ 非頭結點
    class Solution {
        public ListNode removeNthFromEnd(ListNode head, int n) {
            if (head == null) return null;

            ListNode tmpHead = new ListNode(-1);
            tmpHead.next = head;
            ListNode cur = head;
            ListNode prev = tmpHead;
            while (n-- > 0) {
                cur = cur.next;
                if (cur == null ) {
                    //走到末尾   1->2
                    if( n>0){
                        return null;
                    }else if(n==0){
                          tmpHead.next = tmpHead.next.next;
                          return tmpHead.next;
                    }
                }
            }
            //如果删除的節點是頭結點 /非頭結點
            while (cur != null && prev != null) {
                prev = prev.next;
                cur = cur.next;
            }
            ListNode next = prev.next;
            if(next != null){
                prev.next = next.next;
            }else{
                prev.next = null;
            }
            return tmpHead.next;
        }
    }
}
      

官方答案

public ListNode removeNthFromEnd2(ListNode head, int n) {
            ListNode dummy = new ListNode(0); //建立一個假頭
            dummy.next = head;  //假頭指向頭結點
            ListNode first = dummy; //快指針first
            ListNode second = dummy; //慢指針
            // Advances first pointer so that the gap between first and second is n nodes apart
            for (int i = 1; i <= n + 1; i++) {
                first = first.next; //
            }
            //快慢指針同時進行移動
            while (first != null) {
                first = first.next;
                second = second.next;
            }
            //慢指針跳過這個要删除的節點
            second.next = second.next.next;
            return dummy.next;
}