java反轉(zhuǎn)鏈表的多種解決方法舉例詳解
反轉(zhuǎn)鏈表的三種方式
1,使用棧解決
棧是最容易的一種方式了,因?yàn)闂J窍冗M(jìn)后出。實(shí)現(xiàn)原理就是把鏈表節(jié)點(diǎn)一個(gè)個(gè)入棧,全部入棧之后再一個(gè)個(gè)出棧,出棧的時(shí)候在把節(jié)點(diǎn)按照出棧的順序組成一個(gè)新的鏈表。
原理如圖:
代碼如下:
public ListNode ReverseList(ListNode head){ Stack<ListNode> stack = new Stack<>(); //把全部節(jié)點(diǎn)都?jí)喝霔V? while(head != null){ stack.push(head); head = head.next; } //如果stack棧里面沒有數(shù)據(jù),說明head是一個(gè)空指針,因此可以直接返回 //不需要進(jìn)行后續(xù)計(jì)算 if(stack.isEmpty()){ return null; } ListNode node = stack.pop();//出棧的第一個(gè)節(jié)點(diǎn)成為第一個(gè)新鏈表的第一個(gè)節(jié)點(diǎn) ListNode dummy = node; //保留頭節(jié)點(diǎn),用于最后的返回 //把棧中的節(jié)點(diǎn)全部出棧,然后重新連成一個(gè)新的鏈表 while(!stack.isEmpty()){ node.next = stack.pop(); node = node.next;//更換鏈表的最后一個(gè)元素 } //最后一個(gè)節(jié)點(diǎn)就是反轉(zhuǎn)前的頭節(jié)點(diǎn),需要讓他的next為null //不然可能構(gòu)成環(huán) node.next = null; return dummy;//最后返回保存好的頭節(jié)點(diǎn) }
2,雙指針實(shí)現(xiàn)
利用兩個(gè)指針來保存鏈表中數(shù)據(jù),一個(gè)指針用來存儲(chǔ)當(dāng)前節(jié)點(diǎn)中next元素中更改后的值,另一個(gè)指針來指向下一個(gè)需要更改節(jié)點(diǎn)的地址。
原理如圖:
代碼如下:
public ListNode ReverseList(ListNode head) { //當(dāng)前節(jié)點(diǎn)中next元素改變后的值 //初始值為null是因?yàn)楦暮?原第一個(gè)元素 改后最后一個(gè)元素 //next指向的值為null ListNode ChangeNode = null; while (head != null) { //先保存當(dāng)前訪問的節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn) //留著while循環(huán)最后更新數(shù)據(jù)并且 ListNode nextNode = head.next; //把當(dāng)前節(jié)點(diǎn)中next元素進(jìn)行更改,使其可以指向前一個(gè)元素 head.next = ChangeNode; //更新ChangeNode指針,用于下一次節(jié)點(diǎn)next元素更新 ChangeNode = head; //更新節(jié)點(diǎn),去往下一個(gè)節(jié)點(diǎn) head = nextNode; } //循環(huán)之后ChangeNode指向的值為 原最后一個(gè)節(jié)點(diǎn) 改后第一個(gè)節(jié)點(diǎn) //所以返回ChangeNode就是改后的頭節(jié)點(diǎn) return ChangeNode; }
3,遞歸實(shí)現(xiàn)
遞歸實(shí)現(xiàn)是最難的,理由是遞歸本身很難理解。我認(rèn)為遞歸的本質(zhì)是通過不斷的改變參數(shù)找到問題的原點(diǎn),再進(jìn)行返回。邏輯處理部分則是在不斷找尋原點(diǎn)的過程中,或者是找到原點(diǎn)后在返回的過程中進(jìn)行的。這個(gè)題目既可以在找原點(diǎn)的過程中設(shè)置邏輯處理,也可以在返還的過程中進(jìn)行邏輯處理。
找原點(diǎn)的過程中設(shè)置邏輯處理:
public ListNode ReverseList(ListNode head) { //Reverse函數(shù)的兩個(gè)參數(shù)的意思是,當(dāng)前節(jié)點(diǎn)和上一個(gè)節(jié)點(diǎn) //head是原本函數(shù)的頭節(jié),null是更改后頭節(jié)點(diǎn)指向的值 return Reverse(head, null); } public ListNode Reverse(ListNode nowNode, ListNode lastNode) {、 //當(dāng)前節(jié)點(diǎn)是null //說明上一個(gè)節(jié)點(diǎn)是最后一個(gè)節(jié)點(diǎn) if (nowNode == null) { return lastNode; } //先保存下一個(gè)地址的位置 ListNode next = nowNode.next; //讓當(dāng)前節(jié)點(diǎn)指向上一個(gè)節(jié)點(diǎn) nowNode.next = lastNode; //處理完這個(gè)節(jié)點(diǎn)的邏輯之后開始前往下一個(gè)節(jié)點(diǎn) return Reverse(next, nowNode); }
返還的過程中進(jìn)行邏輯處理:
public ListNode ReverseList(ListNode head){ //當(dāng)前節(jié)點(diǎn)的next元素沒有指向下一個(gè)元素的時(shí)候說明這是最后一個(gè)元素 if(head == null || head.next == null){ return head; } //找到最后一個(gè)元素,并開始一層一層的往上傳遞 ListNode last = ReverseList(head.next); //把下一個(gè)元素指向的元素改為自己 //(因?yàn)檫f歸條件的影響當(dāng)前的元素只可能是反轉(zhuǎn)后第二個(gè)元素之后的元素, // 所以head.next.next不會(huì)越界) head.next.next = head; //并且清除當(dāng)前指向的節(jié)點(diǎn),防止可能的問題(成環(huán)) head.next = null; //傳遞最后一個(gè)元素 return last; }
建議先看懂前面兩個(gè)方法再來看最后的遞歸,先看懂這個(gè)題目的基本處理邏輯。
后面兩個(gè)解法的本質(zhì)是指針的運(yùn)用,Java對這方面沒有很好的解釋,所以可能會(huì)有點(diǎn)難理解
總結(jié)
到此這篇關(guān)于java反轉(zhuǎn)鏈表的多種解決方法的文章就介紹到這了,更多相關(guān)java反轉(zhuǎn)鏈表解決方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java SSH 秘鑰連接mysql數(shù)據(jù)庫的方法
這篇文章主要介紹了Java SSH 秘鑰連接mysql數(shù)據(jù)庫的方法,包括引入依賴的代碼和出現(xiàn)異常報(bào)錯(cuò)問題,需要的朋友可以參考下2021-06-06Java使用Hutool+自定義注解實(shí)現(xiàn)數(shù)據(jù)脫敏
我們在使用手機(jī)銀行的時(shí)候經(jīng)常能看到APP上會(huì)將銀行卡的卡號(hào)中間部分給隱藏掉使用 ***** 來代替,在某些網(wǎng)站上查看一些業(yè)務(wù)密碼時(shí)(例如簽到密碼等)也會(huì)使用 ***** 來隱藏掉真正的密碼,那么這種方式是如何實(shí)現(xiàn)的呢,本文將給大家介紹使用Hutool+自定義注解實(shí)現(xiàn)數(shù)據(jù)脫敏2023-09-09Springboot啟動(dòng)同時(shí)創(chuàng)建數(shù)據(jù)庫和表實(shí)現(xiàn)方法
這篇文章主要介紹了Springboot啟動(dòng)同時(shí)創(chuàng)建數(shù)據(jù)庫和表,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01IntelliJ IDEA中出現(xiàn)"PSI and index do not match"錯(cuò)誤的解決辦法
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中出現(xiàn)"PSI and index do not match"錯(cuò)誤的解決辦法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10