[Leetcode] 116, 129, 23

来源:互联网 发布:网络工具书 编辑:程序博客网 时间:2024/06/06 02:16

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) {}//同上,我就不写了};