算法題復習(棧與隊列、二叉樹)

目錄

  • 棧與隊列
    • 棧用于匹配的問題
    • 隊列用于堆
  • 二叉樹系列
    • 深度遍歷,遞歸與迭代
    • 層序遍歷
    • 二叉樹屬性
    • 二叉樹修改與構造
    • 二叉搜索樹
    • 公共祖先
    • 二叉搜索樹的修改與構造

棧與隊列

棧用于匹配的問題

20. 有效的括號
https://leetcode-cn.com/problems/valid-parentheses/
不匹配的三種情況;
1、字符串左方向的括號多余了
2、字符串右方向的括號多余了
3、字符串括號沒有多余,但是類型不匹配。
使用棧的時候三者對應到的棧的情況;
1、已經遍歷完字符串,但是棧不為空
2、遍歷字符串匹配的過程中,棧已經為空了
3、再遍歷字符串匹配的過程中,發現棧中沒有要匹配的字符。

class Solution {
public:bool isValid(string s) {stack<int> st;for(int i = 0; i < s.size(); i++){if(s[i] == '(') st.push(')');else if(s[i] == '[') st.push(']');else if(s[i] == '{') st.push('}');//接下來就是判斷,這個是1、3情況else if(st.empty() || st.top() != s[i]){return false;}//如果匹配,那么出棧else{st.pop();}}//第2種情況,遍歷完字符串,棧不為空return st.empty();}
};

1047. 刪除字符串中的所有相鄰重復項,與上一題思路一致,注意reverse函數的使用。
https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string/

class Solution {
public:string removeDuplicates(string s) {stack<char> st;for(int i = 0; i < s.size(); i++){if(!st.empty() && st.top() == s[i]){st.pop();}elsest.push(s[i]);}string result ="";//將stack中數據輸出while(!st.empty()){result += st.top();st.pop();} //然后倒序reverse(result.begin(),result.end());return result;}
};

150. 逆波蘭表達式求值,做計算器程序的肯定知道這個,不過一般來說我們編寫的是將中綴表達式轉換為逆波蘭表達式。
逆波蘭表達式適合用棧操作運算:遇到數字則入棧;遇到算符則取出棧頂兩個數字進行計算,并將結果壓入棧中。
與前幾題一樣思路,先將stirng轉換成int入棧,tokens[i]是運算符,使用該運算符計算棧頂前兩個元素。
需要注意的編程細節:
1、stack.pop()并不返回棧頂元素。所以要在pop之前,取top元素。
2、 stoi(s1)可以將string類型數據轉化為int類型,比較方便。

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for(int i = 0; i < tokens.size(); i++){if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){int num2 = st.top();st.pop();int num1 = st.top();st.pop();if(tokens[i] == "+"){st.push(num1 + num2);}else if(tokens[i] == "-"){st.push(num1 - num2);}else if(tokens[i] == "*"){st.push(num1 * num2);}else{st.push(num1 / num2);}}else{st.push(stoi(tokens[i]));}}return st.top();}
};

隊列用于堆

347. 前 K 個高頻元素,思路簡單,對容器的使用比較復雜。
1、統計元素出現頻率,使用map
2、對頻率進行排序,使用優先級隊列(從隊頭取元素,從隊尾添加元素,隊列內部自動按照元素的權值排序)
3、找出前K個高頻元素,使用小頂堆,小頂堆每次將最小的元素彈出,最后小頂堆中積累的才是K個最大元素。
構建過程:
1、根據頻率,構建map
2、構建小頂堆,將所有頻率送入堆中,如果堆的大小大于K了,將元素從堆頂彈出。
這里需要注意priority_queue的設置方式:

priority_queue<Type, Container(Type), Functional>

Type 就是數據類型,Container 就是容器類型(Container必須是用數組實現的容器,比如vector,deque等等,但不能用 list。STL里面默認用的是vector),Functional 就是比較的方式,當需要用自定義的數據類型時才需要傳入這三個參數,使用基本數據類型時,只需要傳入數據類型,默認是大頂堆.
這里我們設置成這樣:
送入的是pair對(這里指map),比較方式需要自定義,這里比較的是pair對第二個元素的值,從小到大排序。(注意優先隊列以vector為容器,隊首指向vector后面,隊尾指向vector前面)

 priority_queue< pair<int,int>,vector< pair<int,int> >,mycomparison > pri_que;
class Solution {
public://定義優先隊列的排序方式,根據pair的第二個元素的大小,大的排后面。class mycomparison {public:bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs) {return lhs.second > rhs.second;}};vector<int> topKFrequent(vector<int>& nums, int k) {//統計元素出現頻率unordered_map<int,int> map; //map<nums[i],對應頻次>for(int i = 0; i < nums.size(); i++)map[nums[i]]++;//對頻率排序//定義一個小頂堆,大小為kpriority_queue< pair<int,int>,vector< pair<int,int> >,mycomparison > pri_que;//用固定大小k的小頂堆掃描所有頻率的數值for(unordered_map<int,int>::iterator it = map.begin(); it != map.end(); it++){pri_que.push(*it);if(pri_que.size() > k) pri_que.pop();}//找出前k個高頻元素,因為小頂堆先彈出的是最小的,所以倒序輸出到數組中。vector<int> result(k);for(int i = k - 1; i >= 0; i--){result[i] = pri_que.top().first;pri_que.pop();}return result;}
};

二叉樹系列

二叉樹鏈式存儲方式:

struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x): val(x), left(nullptr), right(nullptr) {}
};

深度遍歷,遞歸與迭代

三種遍歷方式:
144. 二叉樹的前序遍歷
https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
145. 二叉樹的后序遍歷
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
94. 二叉樹的中序遍歷
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

遞歸法模板:前序遍歷為例

class Solution {
public:void traversal(TreeNode* cur,vector<int>& vec){if(cur == nullptr) return;vec.push_back(cur->val);traversal(cur->left,vec);traversal(cur->right,vec);}vector<int> preorderTraversal(TreeNode* root) {vector<int> result;traversal(root,result);return result;}
};

迭代法模板:中序遍歷為例
注意:棧的特性入棧和出棧相反,所以如果想輸出順序為“左中右”,入棧順序必須為“右中左”

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if(root != nullptr) st.push(root);while(!st.empty()){TreeNode* node = st.top();if(node != nullptr){st.pop();if(node->right != nullptr) st.push(node->right);st.push(node);st.push(nullptr);if(node->left != nullptr) st.push(node->left);}else{st.pop();result.push_back(st.top()->val);st.pop();}}return result;}
};

層序遍歷

層序遍歷模板如下:

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que;if(root != nullptr) que.push(root);vector<vector<int>> result;while(!que.empty()) {int size = que.size();vector<int> vec;for(int i = 0; i < size; i++){TreeNode* node = que.front();que.pop();vec.push_back(node->val);if(node->left) que.push(node->left);if(node->right) que.push(node->right);}result.push_back(vec);}return result;}
};

102. 二叉樹的層序遍歷
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
107. 二叉樹的層序遍歷 II
https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
199. 二叉樹的右視圖
https://leetcode-cn.com/problems/binary-tree-right-side-view/
637. 二叉樹的層平均值
https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/
429. N 叉樹的層序遍歷
https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/
515. 在每個樹行中找最大值,注意max初始值取最小值INT_MIN
https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/
116. 填充每個節點的下一個右側節點指針,這一題要注意同層節點之間的鏈接,在單層遍歷的時候記錄本層的頭部節點,然后在遍歷的時候讓前一個節點指向本節點,本層最后一個節點next指向nullptr。
117. 填充每個節點的下一個右側節點指針 II,這兩題代碼一樣。
https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/
https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/

class Solution {
public:Node* connect(Node* root) {queue<Node*> que;if(root != nullptr) que.push(root);while(!que.empty()){int size = que.size();Node* pre;Node* now;for(int i = 0; i < size; i++){//每層第一個元素if(i == 0){pre = que.front();que.pop();now = pre;}else    //非第一個元素{now = que.front();que.pop();pre->next = now;pre = now;}if(now->left) que.push(now->left);if(now->right) que.push(now->right);}//每一層最后一個元素pre->next = nullptr;}return root;}
};

104. 二叉樹的最大深度,層序遍歷,在while循環中++;
https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
111. 二叉樹的最小深度,一樣的思路,不過在每層節點遍歷時需要檢查是否無左右孩子,如果沒有,則立刻返回當前層數。

if(!node->left && !node->right) return result;

二叉樹屬性

101. 對稱二叉樹
https://leetcode-cn.com/problems/symmetric-tree/
遞歸法:外層是對稱的,內層也是對稱的。
確定遞歸函數參數、返回值:

bool compare(TreeNode* left,TreeNode* right)

確定終止條件:
1、左右都為空,返回true
2、左右只有一個為空,返回false
3、左右結點均不為空,比較結點數值,不相同返回false
4、左右結點均不為空,數值相同時,還要繼續向下判斷
確定單層邏輯;
1、比較二叉樹外側是否對稱:傳入左結點的左孩子,右結點的右孩子。
2、比較內側是否對稱,傳入左結點的右孩子,右結點的左孩子。
3、如果左右都對稱就返回true,否則返回false

class Solution {
public:bool compare(TreeNode* left,TreeNode* right){if(!left && !right) return true;else if((!left && right) || (left && !right)) return false;else if(right->val != left->val) return false;//下面就是right->val == left->val的情況了,還得繼續探討bool outside = compare(right->right,left->left);bool inside = compare(right->left,left->right);return (outside && inside);}bool isSymmetric(TreeNode* root) {if(root == nullptr) return true;return compare(root->left,root->right);}
};

關于二叉樹的最小深度與最大深度,在層序遍歷中已經涉及到了
…在此省略
222. 完全二叉樹的節點個數,層序遍歷+節點計數
https://leetcode-cn.com/problems/count-complete-tree-nodes/
110. 平衡二叉樹
https://leetcode-cn.com/problems/balanced-binary-tree/
遞歸三部曲:
1、確定遞歸函數的參數和返回值
傳入當前節點,返回值為當前節點的高度。返回-1表示不是平衡二叉樹
2、終止條件
遇到空節點為終止,返回0,表示當前節點為根節點的高度為0
3、單層的邏輯
判斷當前傳入節點為根節點的二叉樹是否為平衡二叉樹:比較左子樹高度和右子樹高度,差值<=1返回當前二叉樹的高度,否則返回-1.

class Solution {
public:int getDepth(TreeNode* node){if(node == nullptr) return 0;int leftDepth = getDepth(node->left);if(leftDepth == -1) return -1;int rightDepth = getDepth(node->right);if(rightDepth == -1) return -1;int result;if(abs(leftDepth - rightDepth) > 1)return -1;elseresult = 1 + max(leftDepth,rightDepth);return result;}bool isBalanced(TreeNode* root) {if(getDepth(root) != -1) return true;else return false;}
};

257. 二叉樹的所有路徑
遞歸三部曲+前序遍歷+回溯pop+字符串處理即可。

class Solution {
public:void traversal(TreeNode* cur, vector<int>& path,vector<string>& result){path.push_back(cur->val);//到達葉子節點if(cur->left == nullptr && cur->right == nullptr){string sPath;for(int i = 0; i < path.size() - 1; i++){sPath += to_string(path[i]);sPath += "->";}sPath += to_string(path[path.size() - 1]);result.push_back(sPath);return;}//如果不是葉子節點if(cur->left){traversal(cur->left,path,result);path.pop_back();    //回溯}if(cur->right){traversal(cur->right,path,result);path.pop_back();    //回溯}}vector<string> binaryTreePaths(TreeNode* root) {vector<string> result;vector<int> path;if(root == nullptr) return result;traversal(root,path,result);return result;}
};

404. 左葉子之和
https://leetcode-cn.com/problems/sum-of-left-leaves/
如果某節點的左節點不為空,且左節點沒有左右孩子,那么這個節點就是左葉子。
必須通過節點的父節點來判斷其左孩子是不是左葉子。
遞歸三部曲:
1、返回值為數值之和,傳入參數為樹的根節點
2、終止條件:遇到空節點返回
3、單層邏輯:遇到左葉子節點的時候,記錄數值,然后通過遞歸求取左子樹左葉子之和和右子樹左子葉之和,相加便是整個樹的左葉子之和。

class Solution {
public:int sumOfLeftLeaves(TreeNode* root) {if(root == nullptr) return 0;int leftval = sumOfLeftLeaves(root->left);int rightval = sumOfLeftLeaves(root->right);int midval = 0;if(root->left != nullptr && root->left->left == nullptr && root->left->right == nullptr){midval = root->left->val;}int sum = midval + leftval + rightval;return sum;}
};

513. 找樹左下角的值
https://leetcode-cn.com/problems/find-bottom-left-tree-value/
層序遍歷+記錄每一行的第一個節點數值即可。
112. 路徑總和
https://leetcode-cn.com/problems/path-sum/
遞歸三部曲:
1、參數:二叉樹的根節點+一個計數器
這個計數器用來計算二叉樹的一條邊之和是否正好是目標和,計數器為int
返回值:bool
2、終止條件
count初始值為目標和,然后每次減去遍歷路徑點的數值。
如果最后count == 0,同時到了葉子節點的話,說明找到了目標和。
3、單層邏輯
由于終止條件是判斷葉子節點,所以遞歸的過程中不要讓空節點進入遞歸。
如果遞歸函數的返回值為true,說明找到了合適的路徑,應該立即返回。

class Solution {
public:bool traversal(TreeNode* cur,int count){if(cur->left == nullptr && cur->right == nullptr && count == 0) return true;    //遇到葉子節點,并且計數為0if(cur->left == nullptr && cur->right == nullptr) return false;     //遇到葉子節點而沒有找到合適的邊,直接返回if(cur->left) {count -= cur->left->val;if(traversal(cur->left,count)) return true;count += cur->left->val;}if(cur->right) {count -= cur->right->val;if(traversal(cur->right,count)) return true;count += cur->right->val;}//否則return false;}bool hasPathSum(TreeNode* root, int targetSum) {if(root == nullptr) return false;targetSum = targetSum - root->val;return traversal(root,targetSum);}
};

二叉樹修改與構造

226. 翻轉二叉樹
先序遍歷,先交換左右孩子,然后反轉左子樹,反轉右子樹。

class Solution {
public:TreeNode* invertTree(TreeNode* root) {if(root == nullptr) return root;swap(root->left,root->right);invertTree(root->left);invertTree(root->right);return root;}
};

106. 從中序與后序遍歷序列構造二叉樹 比較復雜
https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
步驟:
1、如果數組大小為0的話,說明是空節點
2、如果不為空,取后序數組最后一個元素作為節點元素
3、找到后序數組最后一個元素在中序數組的位置,作為切割點
4、切割中序數組,切成中序左數組和中序右數組。(記住,先切割中序數組!!!)
5、切割后序數組,切成后序左數組和后序右數組
6、遞歸處理左區間和右區間

切割的時候按照左閉右開的原則。后序數組的切割要根據中序數組切割出來的大小,還要注意后序數組在切割前要將最后一個數剔除。

class Solution {
public:TreeNode* traversal(vector<int>& inorder,int Inbegin,int Inend,vector<int>& postorder,int Postbegin,int Postend){//第一步,檢查后序數組大小if(Postbegin == Postend) return nullptr;//第二步:后序數組中最后一個元素,就是當前的中間節點int rootval = postorder[Postend - 1];TreeNode* root = new TreeNode(rootval);//葉子節點if(Postbegin - Postend == 1) return root;//第三步,中序數組找切割點int splitIndex = 0;for(splitIndex = Inbegin; splitIndex < Inend; splitIndex++){if(inorder[splitIndex] == rootval) break;}//第四步,切割中序數組,得到中序左數組和中序右數組int leftInbegin = Inbegin;int leftInend = splitIndex;int rightInbegin = splitIndex+1;int rightInend = Inend;//第五步:切割后序數組,得到后序左數組和后序右數組int leftPostbegin = Postbegin;int leftPostend = Postbegin + leftInend - leftInbegin;int rightPostbegin = leftPostend;int rightPostend = Postend - 1;//第六步,遞歸處理左區間和右區間root->left = traversal(inorder,leftInbegin,leftInend,postorder,leftPostbegin,leftPostend);root->right = traversal(inorder,rightInbegin,rightInend,postorder,rightPostbegin,rightPostend);return root;} TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {if(inorder.size() == 0 || postorder.size() == 0) return nullptr;//左閉右開return traversal(inorder,0,inorder.size(),postorder,0,postorder.size());}
};

105. 從前序與中序遍歷序列構造二叉樹,操作類似
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/submissions/
654. 最大二叉樹
https://leetcode-cn.com/problems/maximum-binary-tree/submissions/

二叉搜索樹

700. 二叉搜索樹中的搜索
遞歸:

    TreeNode* searchBST(TreeNode* root, int val) {if(root == nullptr || root->val == val) return root;if(root->val > val) return searchBST(root->left,val);if(root->val > val) return searchBST(root->right,val);return nullptr;}

98. 驗證二叉搜索樹
二叉搜索樹中序遍歷得到的數組是遞增的。

class Solution {
public:vector<int> vec;void traversal(TreeNode* node){if(node == nullptr) return ;traversal(node->left);vec.push_back(node->val);traversal(node->right);}bool isValidBST(TreeNode* root) {vec.clear();traversal(root);for(int i = 1; i < vec.size(); i++){if(vec[i] <= vec[i - 1]) return false;}return true;}
};

530. 二叉搜索樹的最小絕對差
轉換為有序數組,然后對有序數組進行比較。
501. 二叉搜索樹中的眾數
轉換為有序數組,然后對相鄰兩個元素進行比較,統計相同頻次,有一些細節需要注意。

class Solution {
public:vector<int> vec;void traversal(TreeNode* node){if(node == nullptr) return ;traversal(node->left);vec.push_back(node->val);traversal(node->right);}vector<int> findMode(TreeNode* root) {if(root == nullptr) return {};vec.clear();vector<int> result;traversal(root);unordered_map<int,int> umap;int maxcount = 1;int count = 1;result.push_back(vec[0]);for(int i = 1; i < vec.size(); i++){if(vec[i] == vec[i-1]){count++;}elsecount = 1;if(count == maxcount)result.push_back(vec[i]);if(count > maxcount){maxcount = count;result.clear();result.push_back(vec[i]);}}return result;}
};

538. 把二叉搜索樹轉換為累加樹
https://leetcode-cn.com/problems/convert-bst-to-greater-tree/
定義一個全局變量preval用來存儲上一個節點值,然后右中左遍歷二叉樹。中間節點處理就是加上preaval,然后更新preval。

公共祖先

236. 二叉樹的最近公共祖先
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
通過后序遍歷,回溯,自下向上。
如何判斷一個節點是節點q和節點p的公共祖先:
如果找到一個節點,發現左子樹出現了節點p,右子樹出現了q;或者左子樹出現q,右子樹出現p。那么該節點就是節點p和q的最近公共祖先。

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root == p || root == q || root == nullptr) return root;TreeNode* left = lowestCommonAncestor(root->left,p,q);TreeNode* right = lowestCommonAncestor(root->right,p,q);//如果left和right都不為空,則說明root就是最近公共祖先if(left != nullptr && right != nullptr) return root;if(left == nullptr && right != nullptr) return right;else if(left != nullptr && right == nullptr) return left;else return nullptr;}
};

235. 二叉搜索樹的最近公共祖先
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/submissions/

class Solution {
public:TreeNode* traversal(TreeNode* cur, TreeNode* p, TreeNode* q){if(cur == nullptr) return cur;if(cur->val > p->val && cur->val > q->val) {TreeNode* left = traversal(cur->left,p,q);if(left != nullptr) return left;}if(cur->val < p->val && cur->val < q->val){TreeNode* right = traversal(cur->right,p,q);if(right != nullptr) return right;}//否則說明,cur是最近公共祖先(從底向上)return cur;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {return traversal(root,p,q);}
};

二叉搜索樹的修改與構造

701. 二叉搜索樹中的插入操作
https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/
遍歷二叉搜索樹,然后遇到空節點,插入即可。遞歸函數返回節點。

class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {if(root == nullptr){//插入操作TreeNode* node = new TreeNode(val);return node;}if(root->val > val) root->left = insertIntoBST(root->left,val);if(root->val < val) root->right = insertIntoBST(root->right,val);return root; }
};

450. 刪除二叉搜索樹中的節點
https://leetcode-cn.com/problems/delete-node-in-a-bst/
刪除操作比較麻煩:
1、沒有找到刪除的結點,遍歷到空結點直接返回。
2、找到了刪除的結點:
【1】如果左右孩子都為空,直接刪除這個結點,返回NULL為根結點
【2】如果左孩子為空,右孩子不為空,刪除結點,右孩子補位,返回右孩子作為根結點
【3】如果右孩子為空,左孩子不為空,刪除結點,左孩子補位,返回左孩子作為根結點
【4】如果左右孩子不為空,則將刪除結點的左子樹的頭結點放到刪除結點的右子樹的最左邊結點的左孩子上,返回刪除結點右孩子,作為新的結點

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if(root == nullptr) return root;//如果找到了該節點if(root->val == key) {//第二種情況,左右孩子均空,刪除該節點,返回nullptrif(root->right == nullptr && root->left == nullptr) return nullptr;if(root->left == nullptr) return root->right;else if(root->right == nullptr) return root->left;else{TreeNode* cur = root->right;        //找右子樹最左邊節點while(cur->left != nullptr)cur = cur->left;cur->left = root->left;TreeNode* tmp = root;root = root->right;delete tmp;return root;}}//如果沒有找到,繼續遍歷if(root->val > key) root->left = deleteNode(root->left,key);if(root->val < key) root->right = deleteNode(root->right,key);return root;}
};

669. 修剪二叉搜索樹
https://leetcode-cn.com/problems/trim-a-binary-search-tree/
如果當前結點的值小于low,要對該結點的右孩子進行再次搜索,直到找到滿足區間的結點或者空結點,最后返回right結點
如果當前結點的值大于high,要對該結點的左孩子進行再次搜索,直到找到滿足區間的結點或者空結點,最后返回left結點。
自上而下遍歷檢查,直到整棵樹遍歷完。
依次遍歷結點左右孩子,并將返回的結果作為當前結點的左右孩子。
最后返回當前結點。
返回的結點必然是val在區間內或者是空結點。

class Solution {
public:TreeNode* trimBST(TreeNode* root, int low, int high) {if(root == nullptr) return nullptr;if(root->val < low){//尋找新的節點TreeNode* right = trimBST(root->right,low,high);return right;}if(root->val > high){TreeNode* left = trimBST(root->left,low,high);return left;}//如果在這個區間內,那么就對左右子樹進行操作root->left = trimBST(root->left,low,high);root->right = trimBST(root->right,low,high);return root;}
};

108. 修剪二叉搜索樹
https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/\

class Solution {
public:TreeNode* traversal(vector<int>& nums,int left,int right){//這里我們定義區間是左閉右開的if(left == right) return nullptr;int mid = left + ((right-left) >> 1);TreeNode* node = new TreeNode(nums[mid]);node->left = traversal(nums,left,mid);node->right = traversal(nums,mid+1,right);return node;}TreeNode* sortedArrayToBST(vector<int>& nums) {if(nums.empty()) return nullptr;return traversal(nums,0,nums.size());}
};

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

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

相關文章

bpsk_BPSK的完整形式是什么?

bpskBPSK&#xff1a;二進制相移鍵控 (BPSK: Binary Phase Shift Keying) BPSK is an abbreviation of "Binary Phase Shift Keying". BPSK是“二進制相移鍵控”的縮寫 。 BPSK is also occasionally called phase reversal keying (PRK), or 2PSK, which is the el…

win7 下安裝oracle 10g

oracle 10g 在win7下安裝&#xff0c;提示程序異常終止&#xff0c;發生未知錯誤 在網上搜結果&#xff1a; 修改Oracle 10G\database\stage\prereq\db\refhost.xml 在 </SYSTEM> <CERTIFIED_SYSTEMS>后面添加 <!--Microsoft Windows 7--> <OPERAT…

poj 1703 Find them, Catch them

題目鏈接&#xff1a;http://poj.org/problem?id1703 題目大意&#xff1a;警察抓獲N個罪犯&#xff0c;這些罪犯只可能屬于兩個團伙中的一個&#xff0c;現在給出M個條件&#xff08;D a b表示a和b不在同一團伙&#xff09;&#xff0c;對于每一個詢問(A a b)確定a&#xff0…

雙向a*搜索算法_雙向搜索算法

雙向a*搜索算法什么是雙音搜索&#xff1f; (What is bitonic search?) Searching a bitonic array is known as bitonic search. An array is said to be bitonic if it has an increasing sequence of integers followed immediately by a decreasing sequence of integers.…

關于LRU緩存簡單記錄以及代碼補全。

目錄大概思路時間空間復雜度分析指針操作具體細節代碼雙向鏈表設計私有成員變量設計:構造函數和析構函數設計&#xff1a;get與put具體設計雙向指針的具體細節添加到頭節點函數刪除尾節點函數刪除節點函數刪除節點函數感想今天面試考到LRU&#xff0c;太緊張了&#xff0c;完全…

碼農干貨系列【4】--圖像識別之矩形區域搜索

簡介 定位某個圖片的矩形區域是非常有用的&#xff0c;這個可以通過手動的選擇某個區域來實現定位&#xff0c;圖片相關的軟件都提供了這個功能&#xff1b;也可以像本篇一個通過程序來實現智能定位。前者會有誤差&#xff0c;效率低下&#xff1b;后者選區精度高&#xff0c;效…

算法題復習(回溯)

目錄base code棋盤問題51. N 皇后37. 解數獨組合問題77. 組合未剪枝優化剪枝優化216. 組合總和 III未剪枝優化剪枝優化17. 電話號碼的字母組合39. 組合總和未剪枝優化剪枝優化40. 組合總和 II,挺重要的&#xff0c;涉及到去重了切割問題131. 分割回文串子集問題78. 子集90. 子集…

pfa是什么意思_PFA的完整形式是什么?

pfa是什么意思PFA&#xff1a;預測性故障分析 (PFA: Predictive Failure Analysis) PFA is an abbreviation of Predictive Failure Analysis. It is a technique of a mechanism of the computer that is used to predict impending failures of software or hardware compone…

SqlServer視圖(view)

--上節回顧--1.什么是事務--2.事務的特征--原子性、一致性、隔離性、持久性--3.與事務相關的t-sql命令--開啟事務&#xff1a;begin transaction--提交事務&#xff1a;commit transaction--回滾事務&#xff1a;rollback transaction ----------------視圖-------------------…

Android中的廣播Broadcast詳解

今天來看一下Android中的廣播機制&#xff0c;我們知道廣播Broadcast是Android中的四大組件之一&#xff0c;可見他的重要性了&#xff0c;當然它的用途也很大的&#xff0c;比如一些系統的廣播&#xff1a;電量低、開機、鎖屏等一些操作都會發送一個廣播&#xff0c;具體的And…

sql check約束_在SQL中使用CHECK約束

sql check約束Basically, CHECK constraint is used to LIMIT in columns for the range of values. We can use this constraint for single or multiple columns. 基本上&#xff0c; CHECK約束用于限制值范圍內的列 。 我們可以將此約束用于單列或多列。 In single column,…

.NET線程池

摘要 深度探索 Microsoft .NET提供的線程池&#xff0c; 揭示什么情況下你需要用線程池以及 .NET框架下的線程池是如何實現的&#xff0c;并告訴你如何去使用線程池。 內容 介紹 .NET中的線程池 線程池中執行的函數 使用定時器 同步對象的執行 異步I/O操作 監視線程池 死鎖 有關…

折線分割平面

Input輸入數據的第一行是一個整數C,表示測試實例的個數&#xff0c;然后是C 行數據&#xff0c;每行包含一個整數n(0<n<10000),表示折線的數量。Output對于每個測試實例&#xff0c;請輸出平面的最大分割數&#xff0c;每個實例的輸出占一行。Sample Input2 1 2Sample Ou…

《c++特性》

目錄多態構造函數和析構函數存在多態嗎&#xff1f;虛函數表虛析構函數純虛函數和抽象類運行時多態和編譯時多態的區別繼承設計實例指針對象和普通對象的區別正確初始化派生類方式繼承和賦值的兼容規則protected 和 private 繼承基類與派生類的指針強制轉換如何用C實現C的三大特…

Scala中的while循環

在Scala中的while循環 (while loop in Scala) while loop in Scala is used to run a block of code multiple numbers of time. The number of executions is defined by an entry condition. If this condition is TRUE the code will run otherwise it will not run. Scala中…

Linux操作系統啟動過程

在做開發的過程中&#xff0c;突然發現&#xff0c;要對系統做一些有意義的改變&#xff0c;必須要對操作系統的啟動過程有一定的了解&#xff0c;不然就是修改你都不知道從哪里下手啊&#xff0c;然后就是找來資料看&#xff0c;去網上看別人的博客&#xff0c;有了前一周一些…

方法命名的區別

GetDecimalFromString ExtractDecimal 這2個方法名那個比較好呢。上邊的明顯的是中式英語&#xff0c;單詞拼湊而成的。下邊的更加流暢一些。方法名稱取名還是很有要求的。要通俗易懂還要符合文法。從上邊的可以擴展出什么想法呢。 ExtractDecimalExtractDoubleExtractInt16Ext…

工作排序問題

Problem statement: 問題陳述&#xff1a; Given an array of jobs where every job has a deadline and a profit. Profit can be earned only if the job is finished before the deadline. It is also given that every job takes a single unit of time, so the minimum p…

牛客網與leetcode刷題(高頻題中簡單or中等的)

目錄1、反轉鏈表2、排序3、先序中序后序遍歷4、最小的k個數5、子數組的最大累加和6、 用兩個棧實現隊列7、142. 環形鏈表 II8、20. 有效的括號9、最長公共子串(動態規劃),磕磕絆絆10、二叉樹之字形層序遍歷11、重建二叉樹12、LRU緩存13、合并兩個有序鏈表15、大數加法16、一個二…

AMUL的完整形式是什么?

AMUL&#xff1a;阿南德牛奶聯盟有限公司 (AMUL: Anand Milk Union Limited) AMUL is an abbreviation of Anand Milk Union Limited. It is an Indian milk product cooperative dairy organization that is based in the small town of Anand in the state of Gujarat. AMUL …