7 LintCode 分治題目(一)

2021-10-12 16:43:50 字數 4500 閱讀 7481

當我們求解某些問題時,由於這些問題要處理的資料相當多,或求解過程相當複雜,使得直接求解在時間上相當長,或者根本無法直接求出。對於這類問題,我們往往先把它分解成幾個子問題,找到求出這幾個子問題的解法後,再找到合適的方法,把它們組合成求整個問題的解法。如果這些子問題還較大,難以解決,可以再把它們分成幾個更小的子問題,以此類推,直到可以直接求出解為止。這就是分治策略的基本思想。

描述給一棵非空二叉搜尋樹以及乙個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的路徑上的所有點的顏色...