466. 使用快慢指針把有序鍊表轉換二叉搜索樹

2020-10-31 數據結構和算法

想了解更多數據結構以及算法題,可以關注微信公眾號「數據結構和算法」,每天一題為你精彩解答。

問題描述

給定一個單鍊表,其中的元素按升序排序,將其轉換為高度平衡的二叉搜索樹


本題中,一個高度平衡二叉樹是指一個二叉樹每個節點的左右兩個子樹的高度差的絕對值不超過 1。


示例:


1,快慢指針解決

二叉搜索樹的特點是當前節點大於左子樹的所有節點,並且小於右子樹的所有節點,並且每個節點都具有這個特性。


題中說了,是按照升序排列的單鍊表,我們只需要找到鍊表的中間節點,讓他成為樹的根節點,中間節點前面的就是根節點左子樹的所有節點,中間節點後面的就是根節點右子樹的所有節點,然後使用遞歸的方式再分別對左右子樹進行相同的操作……

這裡就以鍊表1→2→3→4→5為例來畫個圖看一下

我們看到上面鍊表的中間節點3就是二叉搜索樹的根節點,然後再對左右子節點以同樣的方式進行操作……,最後再來看下代碼

public TreeNode sortedListToBST(ListNode head) { //邊界條件的判斷 if (head == null) return null; if (head.next == null) return new TreeNode(head.val); //這裡通過快慢指針找到鍊表的中間結點slow,pre就是中間 //結點slow的前一個結點 ListNode slow = head, fast = head, pre = null; while (fast != null && fast.next != null) { pre = slow; slow = slow.next; fast = fast.next.next; } //鍊表斷開為兩部分,一部分是node的左子節點,一部分是node //的右子節點 pre.next = null; //node就是當前節點 TreeNode node = new TreeNode(slow.val); //從head節點到pre節點是node左子樹的節點 node.left = sortedListToBST(head); //從slow.next到鍊表的末尾是node的右子樹的結點 node.right = sortedListToBST(slow.next); return node;}


2,通過集合list解決

實際上還可以把鍊表中的值全都存儲到集合list中,每次把list分為兩部分,和上面原理一樣

public TreeNode sortedListToBST(ListNode head) { List<Integer> list = new ArrayList<>(); //把鍊表節點值全部提取到list中 while (head != null) { list.add(head.val); head = head.next; } return sortedListToBSTHelper(list, 0, list.size() - 1);}TreeNode sortedListToBSTHelper(List<Integer> list, int left, int right) { if (left > right) return null; //把list中數據分為兩部分 int mid = left + (right - left) / 2; TreeNode root = new TreeNode(list.get(mid)); root.left = sortedListToBSTHelper(list, left, mid - 1); root.right = sortedListToBSTHelper(list, mid + 1, right); return root;}


總結

做這道題我們首先要明白什麼是二叉搜索樹,這題是讓把升序的鍊表轉化為二叉搜索樹,如果是把升序的數組轉化為二叉搜索樹可能就更容易些了,但不管是什麼數據結構,最終實現原理還是一樣的。


相關焦點

  • leetcode樹之將有序數組轉換為二叉搜索樹
    序本文主要記錄一下leetcode樹之將有序數組轉換為二叉搜索樹,轉換為一棵高度平衡二叉搜索樹。本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。示例:給定有序數組: [-10,-3,0,5,9],一個可能的答案是:[0,-3,9,-10,null,5],它可以表示下面這個高度平衡二叉搜索樹: 0 / \ -3 9 / / -10 5來源:力扣(LeetCode)連結:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree
  • 449,快慢指針解決環形鍊表
    為了表示給定鍊表中的環,我們使用整數 pos 來表示鍊表尾連接到鍊表中的位置(索引從 0 開始)。如果 pos 是 -1,則在該鍊表中沒有環。判斷鍊表是否有環應該是老生常談的一個話題了,最簡單的一種方式就是快慢指針,慢指針針每次走一步,快指針每次走兩步
  • 二叉搜索樹遞歸版c++
    2.二叉查找樹是基礎性數據結構,用於構建更為抽象的數據結構,如集合、多重集、關聯數組等。3.二叉查找樹的查找過程和次優二叉樹類似,通常採取二叉鍊表作為二叉查找樹的存儲結構。中序遍歷二叉查找樹可得到一個關鍵字的有序序列,一個無序序列可以透過建構一棵二叉查找樹變成一個有序序列,建構樹的過程即為對無序序列進行查找的過程。
  • 平衡二叉樹專題
    空間複雜度:由於使用了遞歸,這裡的空間複雜度的瓶頸在棧空間,因此空間複雜度為 ,其中 為樹的高度。108. 將有序數組轉換為二叉搜索樹(簡單)108 和 109 基本是一樣的,只不過數據結構不一樣,109 變成了鍊表了而已。
  • 二叉搜索樹迭代版c++
    2.二叉查找樹是基礎性數據結構,用於構建更為抽象的數據結構,如集合、多重集、關聯數組等。3.二叉查找樹的查找過程和次優二叉樹類似,通常採取二叉鍊表作為二叉查找樹的存儲結構。中序遍歷二叉查找樹可得到一個關鍵字的有序序列,一個無序序列可以透過建構一棵二叉查找樹變成一個有序序列,建構樹的過程即為對無序序列進行查找的過程。
  • 網際網路公司高頻面試題目:如何把二叉搜索樹轉成累加樹
    538.把二叉搜索樹轉換為累加樹題目連結:https://leetcode-cn.com/problems/convert-bst-to-greater-tree/>給出二叉 搜索 樹的根節點,該樹的節點值各不相同,請你將其轉換為累加樹(Greater Sum Tree),使每個節點 node 的新值等於原樹中大於或等於 node.val 的值之和。
  • 樹、二叉樹、二叉搜索樹的實現和特性
    「有序樹」,反之稱為 「無序樹」。在有序樹中,一個結點最左邊的子樹稱為 「第一個孩子」,最右邊的稱為 「最後一個孩子」。Binary Search Tree二叉搜索樹,也稱二叉搜索樹、有序二叉樹(Ordered Binary Tree)、排序二叉樹(Sorted Binary Tree),是指一顆空樹或者具有下列性質的二叉樹:
  • 把二叉搜索樹轉換為累加樹
    把二叉搜索樹轉換為累加樹(點擊查看題目)題目描述給定一個二叉搜索樹(Binary Search Tree),把它轉換成為累加樹(Greater Tree),使得每個節點的值是原來的節點值加上所有大於它的節點值之和。
  • 前端學數據結構與算法:理解遞歸及拿力扣鍊表題目練手
    鍊表和樹都是非常適合學習並理解遞歸算法的示例,所以之後全部都會使用遞歸,也是為之後更難理解的回溯打好基礎。合併兩個有序鍊表↓將兩個升序鍊表合併為一個新的升序鍊表並返回。新鍊表是通過拼接給定的兩個鍊表的所有節點組成的。
  • 二叉樹:二叉搜索樹登場
    二叉搜索樹是一個有序樹:若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;若它的右子樹不空因為二叉搜索樹的節點是有序的,所以可以有方向的去搜索。如果root->val > val,搜索左子樹,如果root->val < val,就搜索右子樹,最後如果都沒有搜索到,就返回NULL。
  • LeetCode - 將有序數組轉為二叉搜索樹
    Given the sorted array: [-10,-3,0,5,9],One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \ -3 9 / / -10 5這道題是要將有序數組轉為
  • TypeScript 實戰算法系列:實現二叉搜索樹
    前言樹是一種非順序數據結構,它用於存儲需要快速查找的數據。現實生活中也有許多用到樹的例子,比如:家譜、公司的組織架構圖等。本文將詳解二叉搜索樹並用TypeScript將其實現,歡迎各位感興趣的開發者閱讀本文。
  • 447,雙指針解旋轉鍊表
    一種比較簡單的方式就是先把鍊表連接成一個環,然後再把鍊表在某個合適的位置斷開。我們可以使用兩個指針,一個快指針fast從頭開始遍歷直到走到鍊表的末尾還一個指針slow也是從頭開始,走(len-k%len)步就是我們要返回的鍊表頭,這裡可能有點疑問,為什麼不是走(k%len)步,這是因為我們需要把鍊表後面的(k%len)個移到前面,因為單向鍊表我們沒法從後往前遍歷,所以我們只能從前往後移動(len-k
  • 二叉搜索樹的構建
    1 二叉搜索樹BST二叉搜索樹(Binary Search Tree,簡寫BST),又稱為二叉排序樹或二叉查找樹。其定義為:對於樹中的每個節點,其左子樹的所有節點值都小於該節點的值,其右子樹的所有節點值都大於該節點的值。二叉搜索樹的任意一個子樹也是二叉搜索樹。
  • 將有序數組轉換為二叉搜索樹
    什麼是二叉搜索樹二叉搜索樹(又稱二叉排序樹、二叉查找樹),是指一棵空樹或者具有下列性質的二叉樹:1 若任意節點的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值;2 若任意節點的右子樹不空,則右子樹上所有節點的值均大於或等於它的根節點的值;3 任意節點的左、右子樹也分別為二叉查找樹;我們先觀察題目給的例子:根節點 0 的左邊所有數都
  • 二叉樹:搜索樹的最小絕對差
    「注意是二叉搜索樹」,二叉搜索樹可是有序的。遇到在二叉搜索樹上求什麼最值啊,差值之類的,就把它想成在一個有序數組上求最值,求差值,這樣就簡單多了。遞歸那麼二叉搜索樹採用中序遍歷,其實就是一個有序數組。「在一個有序數組上求兩個數最小差值,這是不是就是一道送分題了。」最直觀的想法,就是把二叉搜索樹轉換成有序數組,然後遍歷一遍數組,就統計出來最小差值了。
  • b樹和b+樹有什麼不同 b樹和b+樹特點區別匯總
    B樹,即二叉搜索樹:1、所有非葉子結點至多擁有兩個兒子(Left和Right);2、所有結點存儲一個關鍵字;3、非葉子結點的左指針指向小於其關鍵字的子樹,右指針指向大於其關鍵字的子樹;B+樹是B-樹的變體,也是一種多路搜索樹:1、其定義基本與B-樹同,除了:2、非葉子結點的子樹指針與關鍵字個數相同;3、非葉子結點的子樹指針P[i],指向關鍵字值屬於[K[i], K[i+1])的子樹(B-樹是開區間);4、為所有葉子結點增加一個鏈指針;5、所有關鍵字都在葉子結點出現;
  • 網際網路公司高頻面試題:二叉搜索樹中的插入操作
    開始修改二叉搜索樹701.二叉搜索樹中的插入操作連結:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/給定二叉搜索樹(BST)的根節點和要插入樹中的值,將值插入二叉搜索樹。
  • 秒殺面試官之二叉搜索樹中序遍歷
    通過中序遍歷二叉搜索樹得到的關鍵碼序列是一個遞增序列。這是二叉搜索樹的一個重要性質,巧妙利用這一性質可以解決一系列二叉搜索樹問題。本系列以以下非遞歸中序遍歷代碼為核心,解決一系列相關問題。二叉搜索樹的最小絕對差(一)算法思路中序遍歷二叉搜索樹,第一個結點外的每個節點與其前一節點的差值,如果該值小於最小絕對差,就用它更新最小絕對差(初始可設為無窮)。