C++實(shí)現(xiàn)LeetCode(116.每個(gè)節(jié)點(diǎn)的右向指針)
[LeetCode] 116. Populating Next Right Pointers in Each Node 每個(gè)節(jié)點(diǎn)的右向指針
You are given a perfect binary tree where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.
Initially, all next pointers are set to NULL.
Example:
Input: {"$id":"1","left":{"$id":"2","left":"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":{"$id":"6","left":null,"next":null,"right":null,"val":6},"next":null,"right":{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}
Output: {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":{"$id":"6","left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"7","left":{"$ref":"5"},"next":null,"right":{"$ref":"6"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1}
Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B.
Note:
- You may only use constant extra space.
- Recursive approach is fine, implicit stack space does not count as extra space for this problem.
這道題實(shí)際上是樹(shù)的層序遍歷的應(yīng)用,可以參考之前的博客 Binary Tree Level Order Traversal,既然是遍歷,就有遞歸和非遞歸兩種方法,最好兩種方法都要掌握,都要會(huì)寫(xiě)。下面先來(lái)看遞歸的解法,由于是完全二叉樹(shù),所以若節(jié)點(diǎn)的左子結(jié)點(diǎn)存在的話,其右子節(jié)點(diǎn)必定存在,所以左子結(jié)點(diǎn)的 next 指針可以直接指向其右子節(jié)點(diǎn),對(duì)于其右子節(jié)點(diǎn)的處理方法是,判斷其父節(jié)點(diǎn)的 next 是否為空,若不為空,則指向其 next 指針指向的節(jié)點(diǎn)的左子結(jié)點(diǎn),若為空則指向 NULL,代碼如下:
解法一:
class Solution { public: Node* connect(Node* root) { if (!root) return NULL; if (root->left) root->left->next = root->right; if (root->right) root->right->next = root->next? root->next->left : NULL; connect(root->left); connect(root->right); return root; } };
對(duì)于非遞歸的解法要稍微復(fù)雜一點(diǎn),但也不算特別復(fù)雜,需要用到 queue 來(lái)輔助,由于是層序遍歷,每層的節(jié)點(diǎn)都按順序加入 queue 中,而每當(dāng)從 queue 中取出一個(gè)元素時(shí),將其 next 指針指向 queue 中下一個(gè)節(jié)點(diǎn)即可,對(duì)于每層的開(kāi)頭元素開(kāi)始遍歷之前,先統(tǒng)計(jì)一下該層的總個(gè)數(shù),用個(gè) for 循環(huán),這樣當(dāng) for 循環(huán)結(jié)束的時(shí)候,該層就已經(jīng)被遍歷完了,參見(jiàn)代碼如下:
解法二:
// Non-recursion, more than constant space class Solution { public: Node* connect(Node* root) { if (!root) return NULL; queue<Node*> q; q.push(root); while (!q.empty()) { int size = q.size(); for (int i = 0; i < size; ++i) { Node *t = q.front(); q.pop(); if (i < size - 1) { t->next = q.front(); } if (t->left) q.push(t->left); if (t->right) q.push(t->right); } } return root; } };
我們?cè)賮?lái)看下面這種碉堡了的方法,用兩個(gè)指針 start 和 cur,其中 start 標(biāo)記每一層的起始節(jié)點(diǎn),cur 用來(lái)遍歷該層的節(jié)點(diǎn),設(shè)計(jì)思路之巧妙,不得不服?。?/p>
解法三:
// Non-recursion, constant space class Solution { public: Node* connect(Node* root) { if (!root) return NULL; Node *start = root, *cur = NULL; while (start->left) { cur = start; while (cur) { cur->left->next = cur->right; if (cur->next) cur->right->next = cur->next->left; cur = cur->next; } start = start->left; } return root; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/116
類(lèi)似題目:
Populating Next Right Pointers in Each Node II
參考資料:
https://leetcode.com/problems/populating-next-right-pointers-in-each-node/
到此這篇關(guān)于C++實(shí)現(xiàn)LeetCode(116.每個(gè)節(jié)點(diǎn)的右向指針)的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)每個(gè)節(jié)點(diǎn)的右向指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++實(shí)現(xiàn)LeetCode(123.買(mǎi)股票的最佳時(shí)間之三)
- C++實(shí)現(xiàn)LeetCode(122.買(mǎi)股票的最佳時(shí)間之二)
- C++實(shí)現(xiàn)LeetCode(121.買(mǎi)賣(mài)股票的最佳時(shí)間)
- C++實(shí)現(xiàn)LeetCode(119.楊輝三角之二)
- C++實(shí)現(xiàn)LeetCode(118.楊輝三角)
- C++實(shí)現(xiàn)LeetCode(120.三角形)
- C++實(shí)現(xiàn)LeetCode(117.每個(gè)節(jié)點(diǎn)的右向指針之二)
- C++實(shí)現(xiàn)LeetCode(128.求最長(zhǎng)連續(xù)序列)
相關(guān)文章
C語(yǔ)言菜鳥(niǎo)基礎(chǔ)教程之常量和變量
在C語(yǔ)言中,常量和變量都是可以用來(lái)存儲(chǔ)和表示數(shù)據(jù)的,常量值在程序執(zhí)行的過(guò)程中是不可變的,而變量是可變的2017-10-10劍指offer之C語(yǔ)言不修改數(shù)組找出重復(fù)的數(shù)字
今天小編就為大家分享一篇關(guān)于劍指offer之C語(yǔ)言不修改數(shù)組找出重復(fù)的數(shù)字,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02C語(yǔ)言重難點(diǎn)之內(nèi)存對(duì)齊和位段
這篇文章主要介紹了C語(yǔ)言重難點(diǎn)之內(nèi)存對(duì)齊和位段,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05C++ OpenCV實(shí)戰(zhàn)之形狀識(shí)別
本案例通過(guò)使用OpenCV中的approxPolyDP進(jìn)行多邊形近似,進(jìn)而進(jìn)行基礎(chǔ)形狀識(shí)別(圓、三角形、矩形、星形…),快跟隨小編一起動(dòng)手嘗試一下2022-07-07C語(yǔ)言?超詳細(xì)梳理總結(jié)動(dòng)態(tài)內(nèi)存管理
動(dòng)態(tài)內(nèi)存是相對(duì)靜態(tài)內(nèi)存而言的。所謂動(dòng)態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存,本文帶你深入探究C語(yǔ)言中動(dòng)態(tài)內(nèi)存的管理2022-03-03