手機(jī)網(wǎng)站在哪里找到外貿(mào)推廣平臺排名
文章目錄
- 題目
- 方法一:節(jié)點(diǎn)加入集合找索引
- 方法二:直接計(jì)算長度,然后找出要刪除的節(jié)點(diǎn)的前一個節(jié)點(diǎn)
- 方法三:棧
- 方法四:前后雙指針
題目
這題的關(guān)鍵在與兩個點(diǎn)
-
一定要設(shè)置一個啞結(jié)點(diǎn),防止刪除第一個元素時(shí),導(dǎo)致空指針異常
-
刪除鏈表的元素其實(shí)就等價(jià)于找到這個元素的前一個元素
方法一:節(jié)點(diǎn)加入集合找索引
先將ListNode存到list 然后直接找到要刪除節(jié)點(diǎn)的前一個節(jié)點(diǎn)即可(node.next = node.next.next)
public static ListNode removeNthFromEnd(ListNode head, int n) {ListNode pre = new ListNode(0, head);//創(chuàng)建啞結(jié)點(diǎn) 解決要刪除的元素時(shí)第一個 空指針異常List<ListNode> list = new ArrayList<>();//將鏈表節(jié)點(diǎn)存到listListNode h = pre;while(h != null){list.add(h);h = h.next;}//找到要刪除的數(shù)的前一個節(jié)點(diǎn)ListNode node = list.get(list.size()-1-(n-1)-1);node.next = node.next.next;return pre.next;}
方法二:直接計(jì)算長度,然后找出要刪除的節(jié)點(diǎn)的前一個節(jié)點(diǎn)
public static ListNode removeNthFromEnd(ListNode head, int n) {//得出鏈表的長度int length = getLength(head);ListNode pre = new ListNode(0, head);//創(chuàng)建啞結(jié)點(diǎn) 解決要刪除的元素時(shí)第一個 空指針異常//倒數(shù)n個 為 length - n + 1int l = length - n + 1;ListNode cur = pre;for (int i = 1; i < l ; i++ ) {cur = cur.next;}cur.next = cur.next.next;return pre.next;}//計(jì)算鏈表長度public static int getLength(ListNode head){int len = 0;while(head !=null){len ++;head = head.next;}return len;}
方法三:棧
依次入棧,直到null 然后要刪除的元素 n = 多少 就彈出對少元素 彈出的元素就是要刪除的元素 例如找n=1 倒數(shù)第一個 則直接彈出棧頂元素刪除即可
此時(shí)當(dāng)彈出n個數(shù)之后 ,此時(shí)棧頂其實(shí)就是要刪除的數(shù)的前一個數(shù)了,也滿足將刪除鏈表元素轉(zhuǎn)換為找到要刪除元素的前一個元素
public static ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);//啞結(jié)點(diǎn) 刪除第一個元素空指針異常Deque<ListNode> stack = new LinkedList<ListNode>(); //棧ListNode cur = dummy;while (cur != null) {stack.push(cur);cur = cur.next;}for(int i = 0; i<n ; i++){stack.pop();//彈出對應(yīng)的棧頂元素 最后彈出的元素就是要刪除的元素}//此時(shí)要刪除的前一個元素時(shí)棧頂元素ListNode pre = stack.peek();pre.next = pre.next.next;return dummy.next;}
方法四:前后雙指針
關(guān)鍵在于指針的設(shè)置,fast起始就比slow快一個節(jié)點(diǎn),然后按照n=? fast往前移動?個位置,然后再slow和fast同步移動,直到fast走到null,此時(shí)slow指向的就是要刪除元素的前一個位置(也就是為什么開始就要fast比slow快一個位置的原因,不然等fast走到null了,結(jié)果slow指向的要刪除的元素,這樣不太好執(zhí)行node.next = node.next.next操作,因?yàn)閯h除鏈表的元素其實(shí)就等價(jià)于找到這個元素的前一個元素)
public static ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);//啞結(jié)點(diǎn) 防止刪除第一個元素空指針異常ListNode fir = head;ListNode bef = dummy;//先指針領(lǐng)先 bef n 個位置for(int i=0;i<n;i++){fir = fir.next;}//當(dāng) fir遍歷到鏈表的末尾時(shí), bef的下一個節(jié)點(diǎn)就是我們需要刪除的節(jié)點(diǎn)。while(fir !=null){fir =fir.next;bef = bef.next;}bef.next = bef.next.next;return dummy.next;}