當我們求解某些問題時,由於這些問題要處理的資料相當多,或求解過程相當複雜,使得直接求解在時間上相當長,或者根本無法直接求出。對於這類問題,我們往往先把它分解成幾個子問題,找到求出這幾個子問題的解法後,再找到合適的方法,把它們組合成求整個問題的解法。如果這些子問題還較大,難以解決,可以再把它們分成幾個更小的子問題,以此類推,直到可以直接求出解為止。這就是分治策略的基本思想。
描述給一棵非空二叉搜尋樹以及乙個target值,找到在bst中最接近給定值的節點值
樣例
輸入: root =
and target =
6.124780
輸出:5
解釋:二叉樹 ,表示如下的樹結構:
5/ \ 49/
/ \ 2810
輸入: root =
and target =
4.142857
輸出:4
解釋:二叉樹 ,表示如下的樹結構:
3/ \ 24/
1
解題思路
對乙個節點,找最接近的值有三個:
在這三個值中選出最小的那個節點,返回val值。
ac**
public
intclosestvalue
(treenode root,
double target)}if
(root.right != null)
}// 返回以該節點為跟的子樹中與target最接近的節點值
return re;
}// 返回兩個數相減的絕對值
public
double
differ
(int val,
double target)
描述
給一棵二叉樹, 找到和為最小的子樹, 返回其根節點。輸入輸出資料範圍都在int內。
lintcode會列印根節點為你返回節點的子樹。保證只有一棵和最小的子樹並且給出的二叉樹不是一棵空樹。
樣例
輸入:
輸出:1
說明這棵樹如下所示:
1/ \ -5
2/ \ / \12
-4-5
整顆樹的和是最小的,所以返回根節點1.
輸入:輸出:
1說明:
這棵樹如下所示:
1這棵樹只有整體這乙個子樹,所以返回1.
解題思路
對於乙個節點:
選出三個中最小的和便可找到最下子樹。
ac**
public
class
solution
// 查詢該子樹的和
public
intaddtree
(treenode root)
if(root.right != null)
if(min > count)
// 返回該節點為根的子樹和
return count;
}}
描述
將一棵二叉樹按照前序遍歷拆解成為乙個假鍊錶
。所謂的假煉表是說,用二叉樹的 right 指標,來表示鍊錶中的 next 指標。
不要忘記將左兒子標記為 null,否則你可能會得到空間溢位或是時間溢位。
樣例
輸入:
輸出:解釋:
1/ \ 2
5/ \ \ 34
61\ 2
\ 3\4
\5\6
輸入:輸出:
解釋: 1
1
解題思路
前序遍歷:根左右
對乙個節點,要按前序遍歷成鏈,那麼要把左兒子變成有右兒子,然後把左兒子子樹的最後乙個的右兒子連線至自己先前的右兒子,然後返回右兒子子樹成鏈後的最後乙個節點。
所以需要乙個函式找到當前節點子樹成鏈後的最後乙個節點,對乙個節點,有四種情況:
ac**
public
void
flatten
(treenode root)
}// 成鏈函式,返回當前節點子樹成鏈後的最後乙個節點
private treenode chain
(treenode root)
if(root.left == null)
if(root.right == null)
// 左右兒子都有
treenode left = root.left;
// 找到左兒子成鏈後的最後乙個節點,將其右兒子接入當前節點的右兒
treenode next =
chain
(left)
; treenode right = root.right;
// 右兒子置為左兒子,左兒子置空
root.right = left;
root.left = null;
next.right = right;
// 返回成鏈後的最後乙個節點
return
chain
(right)
;}
描述
給一棵二叉搜尋樹,寫乙個kthsmallest
函式來找到其中第 k 小的元素。
你可以假設 k 總是有效的,1 ≤ k ≤ 樹的總節點數
。
樣例
輸入:,2
輸出:2
解釋: 1
\ 2
第二小的元素是2。
輸入:,
1輸出:1
解釋: 2
/ \1
3第一小的元素是1。
解題思路
二叉搜尋樹中序遍歷後是乙個有序陣列,陣列的第k位即為第k小的元素,所以中序遍歷走k - 1次便是第k小元素
對二叉搜尋樹的乙個節點,它左子樹所有節點都比它小,右子樹都比它大,所以如果我們知道了左子樹和右子樹的節點個數,我們就能知道第k小的元素在**
ac**
public
class
solution
private treenode findk
(treenode root,
int k)
if(add >= k)
// 左子樹的節點個數 t < k,第 k 小元素在右子樹中,並且是右子樹中的 第(k - t - 1)小元素
return
findk
(root.right, k - add -1)
;}// 記錄每個節點為根的子樹的節點數目
public
intcount
(treenode root)
if(root.right != null)
map.
put(root, add)
;return add;
}}
描述
給定一棵二叉樹,找到兩個節點的最近公共父節點(lca)。
最近公共祖先是兩個節點的公共的祖先節點且具有最大深度。
假設給出的兩個節點都在樹中存在
樣例
輸入:,1
,1輸出:1
解釋: 二叉樹如下(只有乙個節點):
1lca(1
,1)=
1
輸入:,3,
5輸出:4
解釋: 二叉樹如下:
4/ \
37/ \
56lca(3
,5)=
4
解題思路
從根節點開始查詢:
對於乙個節點:
ac**
public
class
solution
// 查詢答案
iscontainab
(root, a, b)
;return ans;
}public
boolean
iscontainab
(treenode root, treenode a, treenode b)
// 左兒子中是否含有 a 或 b
boolean lson =
iscontainab
(root.left, a, b)
;// 右兒子中是否含有 a 或 b
boolean rson =
iscontainab
(root.right, a, b)
;// 左兒子和右兒子分別含有乙個節點, 或者該節點是a,b之一,左右子樹中含有另乙個節點,則該點為最近公共祖先if(
(lson && rson)||(
(root.val == a.val || root.val == b.val)
&&(lson || rson)))
// 返回該節點為根的子樹是否含有 a 或 b
return lson || rson || root.val == a.val || root.val == b.val;
}}
珍寶鴨的力扣練習(7) 分治法題目合集
動態規劃和分治法的區別 動態規劃也是一種分治思想 比如其狀態轉移方程就是一種分治 但與分治演算法不同的是,分治演算法是把原問題分解為若干個子問題,自頂向下求解子問題,合併子問題的解,從而得到原問題的解。動態規劃也是把原始問題分解為若干個子問題,然後自底向上,先求解最小的子問題,把結果存在 中,在求解...
LintCode 題目 下乙個更大的數 I
你有兩個陣列nums1和nums2 互不重複 其中nums1是nums2的子集。在nums2的相應位置找到nums1所有元素的下乙個更大數字。nums1中的數字x的下乙個更大數字是nums2中x右邊第乙個更大的數字。如果它不存在,則為此數字輸出 1。1.nums1和nums2中的所有數字都是唯一的。...
每日一題 4月7日題目精講 樹
樹 時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k 其他語言262144k 64bit io format lld 題目描述 shy有一顆樹,樹有n個結點。有k種不同顏色的染料給樹染色。乙個染色方案是合法的,當且僅當對於所有相同顏色的點對 x,y x到y的路徑上的所有點的顏色...