算法(11)-leetcode-explore-learn-數據結構-鏈表的經典問題

leetcode-explore-learn-數據結構-鏈表3

  • 1.反轉一個鏈表
  • 2.移除鏈表元素
  • 3.奇偶鏈表
  • 4.回文鏈表
  • 5.小結

本系列博文為leetcode-explore-learn子欄目學習筆記,如有不詳之處,請參考leetcode官網:https://leetcode-cn.com/explore/learn/card/linked-list/

所有例題的編程語言為python

1.反轉一個鏈表

leetcode 206
思路1: 迭代求解,將當前結點next信息保存下來,然后將前一個節點的信息存入當前結點的next中。更新當前結點。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def reverseList(self, head):""":type head: ListNode:rtype: ListNode"""if head==None:return headpre_node=Nonecur_node=headwhile(cur_node):next_node=cur_node.nextcur_node.next=pre_nodepre_node=cur_nodecur_node=next_nodereturn pre_node   

思路2:
遞歸:假設鏈表的其余部分都已經被翻轉,現在該如何翻轉它前面的部分。由最后一個開始往前不斷翻轉
在這里插入圖片描述

class Solution(object):def reverseList(self, head):""":type head: ListNode:rtype: ListNode"""if head==None or head.next==None:return headp=self.reverseList(head.next)   # 記錄最后一個結點作為頭指針用的。head.next.next=headhead.next=Nonereturn p

2.移除鏈表元素

刪除鏈表中等于給定值 val 的所有節點。
思路:遍歷鏈表的每一結點,如果值等于給定值將其刪除即可。
注意點:要刪除鏈表節點時,可以使用啞結點技巧,防止刪原鏈表的頭結點。最后返回時,返回dummy.next即可。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def removeElements(self, head, val):""":type head: ListNode:type val: int:rtype: ListNode"""dummy=ListNode(0)dummy.next=headpre_node=dummycur_node=dummy.nextwhile(cur_node):next_node=cur_node.nextif cur_node.val==val:pre_node.next=next_node  # 刪除結點else:pre_node=cur_nodecur_node=next_nodereturn dummy.next

3.奇偶鏈表

給定一個單鏈表,把所有奇數節點和偶數節點(節點 編號的奇偶性)分別排在一起。
思路1:原來的鏈表分成奇偶兩個子鏈表,然后將偶鏈表鏈接到奇鏈表后面。
沒有使用額外的空間,直接從原來的鏈表中截取。

# Definition for singly-linked list.
class ListNode(object):def __init__(self, x):self.val = xself.next = Noneclass Solution(object):def oddEvenList(self, head):""":type head: ListNode:rtype: ListNode"""if head==None:return headeven_h=ListNode(0)even_node=even_hcur_node=headi=1while(cur_node):next_node=cur_node.nextif i %2==0:cur_node.next=None   # 將node.next的值給設置為零,能防止成環even_node.next=cur_nodeeven_node=even_node.nextpre_node.next=next_nodeelse:pre_node=cur_nodecur_node=next_nodei+=1cur_node=head.nextpre_node=headwhile(cur_node):print(pre_node.val)pre_node=cur_nodecur_node=cur_node.nextpre_node.next=even_h.nextreturn head        

4.回文鏈表

判斷一個鏈表是否為回文鏈表。
o(n)時間復雜度,o(1)空間復雜度

思路1:可以先把鏈表裝進數組中,判斷數組中元素是否構成回文。數組的前后遍歷比單鏈表方便。時間復雜度o(n),空間復雜度o(n)

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution(object):def isPalindrome(self, head):""":type head: ListNode:rtype: bool"""if not head or not head.next:return Truelst=[]p=headwhile(p):lst.append(p.val)p=p.nextreturn lst==lst[::-1]

思路2:翻轉原鏈表,對照兩個鏈表是否一致,如果回文鏈表應該是一致的,反之原鏈表不為回文鏈表。時間復雜度o(n),空間復雜度o(n)

# Definition for singly-linked list.
class ListNode(object):def __init__(self, x):self.val = xself.next = Noneclass Solution(object):def isPalindrome(self, head):""":type head: ListNode:rtype: bool"""if head==None or head.next==None:return True# 備份原鏈表head_be=ListNode(0)node=headnode_be=head_be    while(node):node_be.next=ListNode(node.val)node_be=node_be.nextnode=node.next# 轉置原鏈表pre_node=Nonecur_node=headwhile(cur_node):next_node=cur_node.nextcur_node.next=pre_nodepre_node=cur_nodecur_node=next_node# 比較兩個鏈表node_be=head_be.nextnode_af=pre_nodewhile(node_be and node_af):if node_be.val!=node_af.val:return Falsenode_be=node_be.nextnode_af=node_af.nextreturn True

思路三:避免使用 O(n)O(n) 額外空間的方法就是改變輸入。

我們可以將鏈表的后半部分反轉(修改鏈表結構),然后將前半部分和后半部分進行比較。比較完成后我們應該將鏈表恢復原樣。雖然不需要恢復也能通過測試用例,因為使用該函數的人不希望鏈表結構被更改。

class Solution(object):def isPalindrome(self, head):""":type head: ListNode:rtype: bool"""if not head or not head.next:return True# 計算鏈表長度p1=headn=1while(p1.next):p1=p1.nextn+=1p1=headp2=headif n==2:if  head.val==head.next.val:return Trueelse:return False# 找鏈表中點for i in range(int(round(n/2.0))-1): # 0p1=p1.nexthalf_end=p1     # 前一半鏈表的最后一個節點# 翻轉后一半鏈表p1=p1.nextpre_node=Nonefor i in range(int(n/2.0)): # 0,1next_node=p1.nextp1.next=pre_nodepre_node=p1p1=next_nodehalf_end.next=pre_nodep1=head# 比較前一半和翻轉后的后一半。for i in range(int(round(n/2.0))): # 0,1p1=p1.nextfor i in range(int(n/2)):# 0,1if p1.val!=p2.val:return Falsep1=p1.nextp2=p2.nextreturn True

5.小結

1.使用鏈表時不易調試,自己多嘗試幾個測試用例總是很有用的,通過輸出鏈表節點的值來觀測代碼運行情況。

2.多指針時,為指針設定合適的名稱,防止自己被搞混

3.單鏈表操作時,儲存前一個節點的信息往往是有效的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445042.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445042.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445042.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

探索式軟件測試

James A.Whittaker [美] 詹姆斯惠特克(軟件測試領域絕對的大師)著作《Exploratory Software Testing》,中文名《探索式軟件測試》,記得當時被這本書深深吸引啦(我不知道有多少做測試的小伙伴看過這本書)&am…

Linux線程池的設計

我設計這個線程池的初衷是為了與socket對接的。線程池的實現千變萬化,我得這個并不一定是最好的,但卻是否和我心目中需求模型的。現把部分設計思路和代碼貼出,以期拋磚引玉。個人比較喜歡搞開源,所以大家如果覺得有什么需要改善的…

算法(12)-leetcode-explore-learn-數據結構-雙鏈表的設計

leetcode-explore-learn-數據結構-鏈表4雙鏈表的設計本系列博文為leetcode-explore-learn子欄目學習筆記,如有不詳之處,請參考leetcode官網:https://leetcode-cn.com/explore/learn/card/linked-list/所有例題的編程語言為python 雙鏈表的設…

安全方面知識

什么是文件上傳漏洞 文件上傳漏洞是指 由于程序員在對用戶文件上傳部分的控制不足或者處理缺陷,而導致的用戶可以越過其本身權限向服務器上上傳可執行的動態腳本文件 這里上傳的文件可以是木馬,病毒,惡意腳本或者WebShell等。 這種攻擊方式是…

CE游戲外掛工具

CHEAT ENGINE(以下簡稱CE)是我見過的最優秀的游戲作弊工具。它的優點多不勝數,雖然單獨從搜索游 戲里面的數值來說,它并不比其他同類軟件強多少,但它不僅僅是個游戲修改工具,它還有其他游戲修改軟件所沒有的一些特點,例…

外掛編程-動作模擬技術

幾乎所有的游戲都有大量繁瑣和無聊的攻擊動作以增加玩家的 功力,還有那些數不完的迷宮,這些好像已經成為了角色游戲的代名詞。現在,外掛可以幫助玩家從這些繁瑣而無聊 的工作中擺脫出來。 1. 鼠標模擬技術 幾乎所有的游戲中都使用了鼠標來改變角色的位置和方向,玩家僅用…

算法(13)-leetcode-explore-learn-數據結構-鏈表小結

leetcode-explore-learn-數據結構-鏈表51.小結2.例題2.1合并兩個有序鏈表思路1:迭代思路2:遞歸2.2 兩數相加2.3 扁平化多級雙向鏈表2.4 復制帶隨機指針的鏈表2.5 旋轉鏈表本系列博文為leetcode-explore-learn子欄目學習筆記,如有不詳之處,請參考leetcode…

leetcode121買賣股票的最佳時機

給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。 如果你最多只允許完成一筆交易(即買入和賣出一支股票),設計一個算法來計算你所能獲取的最大利潤。 注意你不能在買入股票前賣出股票。 示例 1: 輸入: [7,1,5,3,6,…

epoll的內核實現

epoll是由一組系統調用組成。 int epoll_create(int size); int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout); select/poll的缺點在于&#xff1…

算法(14)-數據結構-二叉樹

leetcode-explore-learn-數據結構-二叉樹10.概述1.深度優先遍歷dfs1.1先序遍歷-中左右1.2中序遍歷-左中右1.3后序遍歷-左右中2.廣度優先遍歷bfs3.遍歷-常見問題3.1 二叉樹的最大深度自頂向下自底向上3.2對稱二叉樹3.3路徑總和4.重構-常見問題4.1根據中序和后序遍歷序列構造二叉…

多進程魚多線程的權衡選擇

最近有好多人在網上問道做游戲開發框架用多線程還是多進程呢,或者兩者之間的優缺點,等等類似的問題。下邊小高就帶您小小分析一下: 1、首先要明確進程和線程的含義:進程(Process)是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,是系統進行資源分配和調度的一…

leetcode322 零錢兌換

給定不同面額的硬幣 coins 和一個總金額 amount。編寫一個函數來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。 示例 1: 輸入: coins [1, 2, 5], amount 11 輸出: 3 解釋: 11 5 5 1 示例 2: 輸入: coins [2],…

給數據減肥 讓MySQL數據庫跑的更快

在數據庫優化工作中,使數據盡可能的小,使表在硬盤上占據的空間盡可能的小,這是最常用、也是最有效的手段之一。因為縮小數據,相對來說可以提高硬盤的讀寫速度,并且在查詢過程中小表的內容處理時所占用的系統資源比較少…

算法(15)-leetcode-explore-learn-數據結構-運用遞歸解決二叉樹的問題

leetcode-explore-learn-數據結構-二叉樹2本系列博文為leetcode-explore-learn子欄目學習筆記,如有不詳之處,請參考leetcode官網:https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/

leetcode538 把二叉搜索樹轉換成累加樹

給定一個二叉搜索樹(Binary Search Tree),把它轉換成為累加樹(Greater Tree),使得每個節點的值是原來的節點值加上所有大于它的節點值之和。 對于每一個點來說,自己的父,和自己父的右子樹都是大…

AWK常用命令華(1)

awk 調用: 1.調用awk:

AWk的調用精華

awk 的調用方式 awk 提供了適應多種需要的不同解決方案,它們是: 一、awk 命令行,你可以象使用普通UNIX 命令一樣使用awk,在命令行中你也可以使用awk 程序設計語言,雖然awk 支持多行的錄入,但是錄入長長的命令行并保證其正 確無誤卻是一件令人頭疼的事,因此,這種方法一般…

算法(16)-leetcode-explore-learn-數據結構-二叉樹總結

leetcode-explore-learn-數據結構-二叉樹3本系列博文為leetcode-explore-learn子欄目學習筆記,如有不詳之處,請參考leetcode官網:https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/2/traverse-a-tree/7/所有例題的編程…

leetcode15 三數之和

給定一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a b c 0 ?找出所有滿足條件且不重復的三元組。 注意:答案中不可以包含重復的三元組。 例如, 給定數組 nums [-1, 0, 1,…

AWK再次認識--內置的參數,以及編寫腳本

原本這是篇給公司內同事寫的培訓文章,對于初學awk的人還蠻有幫助,貼到這里與大家共享一下。 〇、前言 意見反饋,請mailto:datouwanggmail.com。 一、AWK簡介 AWK名字來源于三位創造者Aho、Weinberger和Kernighan統稱。 AWK擅長處理文本數據。…