中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

LeetCode反轉(zhuǎn)鏈表的方式有哪些

這篇文章主要為大家展示了“LeetCode反轉(zhuǎn)鏈表的方式有哪些”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“LeetCode反轉(zhuǎn)鏈表的方式有哪些”這篇文章吧。

創(chuàng)新互聯(lián)建站是一家專注于做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),石鼓網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:石鼓等地區(qū)。石鼓做網(wǎng)站價(jià)格咨詢:18982081108

問題描述

定義一個(gè)函數(shù),輸入一個(gè)鏈表的頭節(jié)點(diǎn),反轉(zhuǎn)該鏈表并輸出反轉(zhuǎn)后鏈表的頭節(jié)點(diǎn)。

示例:

輸入: 1->2->3->4->5->NULL

輸出: 5->4->3->2->1->NULL

限制:

0 <= 節(jié)點(diǎn)個(gè)數(shù) <= 5000

使用棧解決    

鏈表的反轉(zhuǎn)是老生常談的一個(gè)問題了,同時(shí)也是面試中常考的一道題。最簡(jiǎn)單的一種方式就是使用,因?yàn)?strong>棧是先進(jìn)后出的。實(shí)現(xiàn)原理就是把鏈表節(jié)點(diǎn)一個(gè)個(gè)入棧,當(dāng)全部入棧完之后再一個(gè)個(gè)出棧,出棧的時(shí)候在把出棧的結(jié)點(diǎn)串成一個(gè)新的鏈表。原理如下

LeetCode反轉(zhuǎn)鏈表的方式有哪些    

代碼比較簡(jiǎn)單,來看下

 1public ListNode reverseList(ListNode head) {
2    Stack<ListNode> stack = new Stack<>();
3    //把鏈表節(jié)點(diǎn)全部摘掉放到棧中
4    while (head != null) {
5        stack.push(head);
6        head = head.next;
7    }
8    if (stack.isEmpty())
9        return null;
10    ListNode node = stack.pop();
11    ListNode dummy = node;
12    //棧中的結(jié)點(diǎn)全部出棧,然后重新連成一個(gè)新的鏈表
13    while (!stack.isEmpty()) {
14        ListNode tempNode = stack.pop();
15        node.next = tempNode;
16        node = node.next;
17    }
18    //最后一個(gè)結(jié)點(diǎn)就是反轉(zhuǎn)前的頭結(jié)點(diǎn),一定要讓他的next
19    //等于空,否則會(huì)構(gòu)成環(huán)
20    node.next = null;
21    return dummy;
22}
   

雙鏈表求解


     

     

雙鏈表求解是把原鏈表的結(jié)點(diǎn)一個(gè)個(gè)摘掉,每次摘掉的鏈表都讓他成為新的鏈表的頭結(jié)點(diǎn),然后更新新鏈表。下面以鏈表1→2→3→4為例畫個(gè)圖來看下。

LeetCode反轉(zhuǎn)鏈表的方式有哪些

LeetCode反轉(zhuǎn)鏈表的方式有哪些

他每次訪問的原鏈表節(jié)點(diǎn)都會(huì)成為新鏈表的頭結(jié)點(diǎn),最后再來看下代碼

 1public ListNode reverseList(ListNode head) {
2    //新鏈表
3    ListNode newHead = null;
4    while (head != null) {
5        //先保存訪問的節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),保存起來
6        //留著下一步訪問的
7        ListNode temp = head.next;
8        //每次訪問的原鏈表節(jié)點(diǎn)都會(huì)成為新鏈表的頭結(jié)點(diǎn),
9        //其實(shí)就是把新鏈表掛到訪問的原鏈表節(jié)點(diǎn)的
10        //后面就行了
11        head.next = newHead;
12        //更新新鏈表
13        newHead = head;
14        //重新賦值,繼續(xù)訪問
15        head = temp;
16    }
17    //返回新鏈表
18    return newHead;
19}

遞歸解決


     

     

我們?cè)賮砘仡櫼幌逻f歸的模板,終止條件,遞歸調(diào)用,邏輯處理。

 1public ListNode reverseList(參數(shù)0) {
2    if (終止條件)
3        return;
4
5    邏輯處理(可能有,也可能沒有,具體問題具體分析)
6
7    //遞歸調(diào)用
8    ListNode reverse = reverseList(參數(shù)1);
9
10    邏輯處理(可能有,也可能沒有,具體問題具體分析)
11}

終止條件就是鏈表為空,或者是鏈表沒有尾結(jié)點(diǎn)的時(shí)候,直接返回

if (head == null || head.next == null)    return head;

遞歸調(diào)用是要從當(dāng)前節(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)開始遞歸。邏輯處理這塊是要把當(dāng)前節(jié)點(diǎn)掛到遞歸之后的鏈表的末尾,看下代碼

 1public ListNode reverseList(ListNode head) {
2    //終止條件
3    if (head == null || head.next == null)
4        return head;
5    //保存當(dāng)前節(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)
6    ListNode next = head.next;
7    //從當(dāng)前節(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)開始遞歸調(diào)用
8    ListNode reverse = reverseList(next);
9    //reverse是反轉(zhuǎn)之后的鏈表,因?yàn)楹瘮?shù)reverseList
10    // 表示的是對(duì)鏈表的反轉(zhuǎn),所以反轉(zhuǎn)完之后next肯定
11    // 是鏈表reverse的尾結(jié)點(diǎn),然后我們?cè)侔旬?dāng)前節(jié)點(diǎn)
12    //head掛到next節(jié)點(diǎn)的后面就完成了鏈表的反轉(zhuǎn)。
13    next.next = head;
14    //這里head相當(dāng)于變成了尾結(jié)點(diǎn),尾結(jié)點(diǎn)都是為空的,
15    //否則會(huì)構(gòu)成環(huán)
16    head.next = null;
17    return reverse;
18}

因?yàn)檫f歸調(diào)用之后head.next節(jié)點(diǎn)就會(huì)成為reverse節(jié)點(diǎn)的尾結(jié)點(diǎn),我們可以直接讓head.next.next = head;,這樣代碼會(huì)更簡(jiǎn)潔一些,看下代碼

1public ListNode reverseList(ListNode head) {
2    if (head == null || head.next == null)
3        return head;
4    ListNode reverse = reverseList(head.next);
5    head.next.next = head;
6    head.next = null;
7    return reverse;
8}

這種遞歸往下傳遞的時(shí)候基本上沒有邏輯處理,當(dāng)往回反彈的時(shí)候才開始處理,也就是從鏈表的尾端往前開始處理的。我們還可以再來改一下,在鏈表遞歸的時(shí)候從前往后處理,處理完之后直接返回遞歸的結(jié)果,這就是所謂的尾遞歸,這種運(yùn)行效率要比上一種好很多

 1public ListNode reverseList(ListNode head) {
2    return reverseListInt(head, null);
3}
4
5private ListNode reverseListInt(ListNode head, ListNode newHead) {
6    if (head == null)
7        return newHead;
8    ListNode next = head.next;
9    head.next = newHead;
10    return reverseListInt(next, head);
11}

尾遞歸雖然也會(huì)不停的壓棧,但由于最后返回的是遞歸函數(shù)的值,所以在返回的時(shí)候都會(huì)一次性出棧,不會(huì)一個(gè)個(gè)出棧這么慢。但如果我們?cè)賮砀囊幌拢裣旅娲a這樣又會(huì)一個(gè)個(gè)出棧了

 1public ListNode reverseList(ListNode head) {
2    return reverseListInt(head, null);
3}
4
5private ListNode reverseListInt(ListNode head, ListNode newHead) {
6    if (head == null)
7        return newHead;
8    ListNode next = head.next;
9    head.next = newHead;
10    ListNode node = reverseListInt(next, head);
11    return node;
12}

以上是“LeetCode反轉(zhuǎn)鏈表的方式有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

本文標(biāo)題:LeetCode反轉(zhuǎn)鏈表的方式有哪些
本文路徑:http://www.rwnh.cn/article34/jcjppe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司、云服務(wù)器App設(shè)計(jì)、營(yíng)銷型網(wǎng)站建設(shè)網(wǎng)站制作、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
运城市| 宣武区| 平乐县| 玛沁县| 桐柏县| 井陉县| 黄龙县| 博罗县| 进贤县| 新民市| 赫章县| 卢湾区| 无棣县| 长岛县| 攀枝花市| 石家庄市| 平谷区| 江津市| 凉城县| 湘乡市| 明光市| 吴桥县| 潜山县| 海阳市| 吴江市| 乐昌市| 平塘县| 苍山县| 牙克石市| 故城县| 仲巴县| 五大连池市| 安顺市| 唐河县| 南开区| 永春县| 湘西| 家居| 泾源县| 江门市| 贵阳市|