116. Populating Next Right Pointers in Each Node
Given a binary tree
struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *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
.
Note:
- You may only use constant extra space.
- You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
For example,
Given the following perfect binary tree,
1 / \ 2 3 / \ / \ 4 5 6 7
After calling your function, the tree should look like:
1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL
Solution: 递归,注意题目中已经限定了是perfect binary tree ,因此不需要讨论很多种情况。
Code:
/**
* Definition for binary tree with next pointer.
* struct TreeLinkNode {
* int val;
* TreeLinkNode *left, *right, *next;
* TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
* };
*/
class Solution {
public:
void connect(TreeLinkNode *root) {
connect(root, NULL);
}
private:
void connect(TreeLinkNode *root, TreeLinkNode *next){
if(root==NULL) return;
root->next = next;
connect(root->left, root->right);
connect(root->right, next!=NULL?next->left:NULL);
}
};
129. Sum Root to Leaf Numbers
Given a binary tree containing digits from 0-9
only, each root-to-leaf path could represent
a number.
An example is the root-to-leaf path 1->2->3
which represents the number 123
.
Find the total sum of all root-to-leaf numbers.
For example,
1 / \ 2 3
The root-to-leaf path 1->2
represents the number 12
.
The root-to-leaf path 1->3
represents the number 13
.
Return the sum = 12 + 13 = 25
.
Solution: 树的递归。
Code:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int sumNumbers(TreeNode* root) {
sumNumbers(root, 0);
return sum;
}
private:
int sum = 0;
void sumNumbers(TreeNode* root, int cur){
if(root==NULL) return;
cur = cur*10 + root->val;
if(root->left==NULL && root->right==NULL){
sum += cur;
}else{
sumNumbers(root->left, cur);
sumNumbers(root->right, cur);
}
cur = cur/10;
}
};
23. Merge k Sorted Lists
Merge k sorted
linked lists and return it as one sorted list. Analyze and describe its complexity.
Solution(1): 直接做,时间复杂度为O(kn),k是数组list的长度,n是待排序的数的总数,当k比较大的时候,无法等同于O(n),Leetcode上会超时。
Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode dummy(INT_MAX);
ListNode* cur = &dummy;
int mini = -1;
int k = 20;
while(1){
mini = -1;
for(int i=0; i<lists.size(); i++){
if(lists[i]!=NULL){
if(mini < 0){
mini = i;
}else if(lists[i]->val<lists[mini]->val){
mini = i;
}
}
}
if(mini<0) break;
cur->next = lists[mini];
cur = cur->next;
lists[mini] = lists[mini]->next;//注意要修改lists数组中的值,不能直接提取指针然后修改
}
return dummy.next;
}
};
Solution(2): 两个两个的merge,直到将所有的链表都merge到一起,时间复杂度大约是O((nk)/2),Leetcode运行时间222ms,因为leetcode给的时间限制不严格,这样做也可以过。复用Merge Two Sorted Lists的函数。
Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* start = NULL;
for(int i=0; i<lists.size(); i++){
start = mergeTwoLists(start, lists[i]);
}
return start;
}
private:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==NULL) return l2;
else if(l2==NULL) return l1;
ListNode* start = NULL;
if(l1->val < l2->val){
start = l1;
l1 = l1->next;
}else{
start = l2;
l2 = l2->next;
}
ListNode* cur = start;
while(l1!=NULL && l2!=NULL){
if(l1->val < l2->val){
cur->next = l1;
l1 = l1->next;
}else{
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
if(l1!=NULL) cur->next = l1;
else if(l2!=NULL) cur->next = l2;
return start;
}
};
Solution(3): 将上面的做法加以改进,使用分治法,可以得到O(nlogn)的解法,Leetcode运行时间26ms。
Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
return mergeKLists(lists.begin(), lists.end());
}
private:
ListNode* mergeKLists(vector<ListNode*>::iterator itbegin, vector<ListNode*>::iterator itend){
if(itbegin>=itend) return NULL;
if((itend-itbegin)==1) return *itbegin;
if((itend-itbegin)==2) return mergeTwoLists(*itbegin, *(itbegin+1));
auto mid = itbegin + (itend-itbegin)/2;
return mergeTwoLists(mergeKLists(itbegin, mid),mergeKLists(mid, itend));
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {}//同上,我就不写了
};