leetcode题解日练--2016.7.19

日练三题,冰冻三尺非一日之寒。

今日题目:1、在旋转有序数组中查找特定元素II;2、将二叉树展平为链表;❤3、实现一个展平堆叠列表的迭代器。

今日摘录:

人生如逆旅,我亦是行人。
——苏轼《临江仙》

81. Search in Rotated Sorted Array II | Difficulty: Medium

Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.

Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.

题意:在一个旋转过的排序数组中去查找某个值是否存在于一个数组中。

思路:
1、最好能够画图来思考这个问题,平均时间复杂度O(logN),最坏情况O(N)。

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int size = nums.size();
        if(size<=0) return false;
        int left = 0,right=size-1;
        while(left<right)
        {
            int mid = left+(right-left)/2;

            if(nums[mid]==target)   return true;
            //如果当前中间元素没找到的情况下,此时分为三种情况:
            //第一种情况是当前mid左边元素是排序好的,这个时候如果target比left元素大比mid元素小,此时target一定在mid的左边,否则就一定不在左边
            if(nums[mid]>nums[left])
            {
                if(nums[mid]>target&&nums[left]<=target)    right = mid-1;
                else    left = mid+1;
            }
            //第二种情况是当前mid右边的元素是排序好的,这个时候如果target大于mid小于right,则target一定在mid右边,否则就一定不在右边
            else if(nums[left]>nums[mid])
            {
                if(nums[mid]<target&&nums[right]>=target)   left = mid+1;
                else    right = mid-1;
            }
            //第三种情况是mid和left相等并且都不等于target,此时无法判断target在mid左边还是右边,所以只能逐个遍历
            else    left++;
        }
        return nums[left]==target;
    }
};

结果:8ms

114. Flatten Binary Tree to Linked List | Difficulty: Medium

Given a binary tree, flatten it to a linked list in-place.
For example,

Given
        1
       / \
      2   5
     / \   \
    3   4   6

The flattened tree should look like:
  1
   \
    2
     \
      3
       \
        4
         \
          5
           \
            6

题意:给定一棵二叉树,将其展平为一个链表,不能使用额外的空间。

思路:
1、其实就是先序遍历,很显然DFS是可以做的,利用一个额外的栈来进行存储

/**
 * 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:
    void flatten(TreeNode* root) {
        if(!root)   return;
        TreeNode* cur;
        stack<TreeNode*>nodes;
        nodes.push(root);
        while(!nodes.empty())
        {
            cur = nodes.top();
            nodes.pop();
            if(cur->right)  nodes.push(cur->right);
            if(cur->left)   nodes.push(cur->left);
            if(nodes.size()>0)  {cur->left = NULL;cur->right = nodes.top();}
        }
        return ;
    }
};

结果:8ms

2、尝试不用额外的空间,那么回顾一下我们如何进行先序遍历?对于根节点,先访问根节点,再访问根节点的左子树,最后访问根节点的右子树。但是,如果在就地更改根节点的指向之后会丢失右子树的根节点,为了保持信息不丢失,还需要将左边子树的最右节点和右子树的根节点建立联系。然后只要迭代得将根节点替换成当前根节点的右节点就行。
建议根据代码在纸上模拟一遍就清楚了。

/**
 * 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:
    void flatten(TreeNode* root) {
        if(!root)   return;
        TreeNode* cur=root;
        TreeNode*pre=NULL;
        while(cur)
        {
            if(cur->left)
            {
            pre = cur->left;
            while(pre->right) pre = pre->right;
            pre->right = cur->right;
            cur->right=cur->left;
            cur->left = NULL;
            }
            cur = cur->right;
        }
        return ;
    }
};

结果:8ms

3、看了讨论一个200+赞答案,使用的是bottom-up recursion的方法,思路非常好,看了他的思路自己用cpp写了巩固一遍,必须马克。
https://discuss.leetcode.com/topic/11444/my-short-post-order-traversal-java-solution-for-share

/**
 * 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 {
private:
    TreeNode *pre=NULL;
public:
    void flatten(TreeNode* root) {
        if(!root)   return;
        flatten(root->right);
        flatten(root->left);
        root->right = pre;
        root->left = NULL;
        pre = root;
    }
};

结果:8ms

341. Flatten Nested List Iterator | Difficulty: Medium

Given a nested list of integers, implement an iterator to flatten it.
Each element is either an integer, or a list – whose elements may also be integers or other lists.
Example 1:
Given the list [[1,1],2,[1,1]],
By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].

Example 2:
Given the list [1,[4,[6]]],
By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6].

题意:给了一个嵌套的列表,实现一个迭代器使得能够将其展平。

思路:
1、发现自己还是对面向对象这块的设计题目理解不清,先mark,这两天将其弄懂。

class NestedIterator {public:
   NestedIterator(vector<NestedInteger> &nestedList) {
       begins.push(nestedList.begin());
       ends.push(nestedList.end());
   }    
int next() {
        //hasNext();        
        return (begins.top()++)->getInteger();
   }   
bool hasNext() {        
    while (begins.size()) {            
        if (begins.top() == ends.top()) {
               begins.pop();
               ends.pop();
           } else {                
                auto x = begins.top();                
                if (x->isInteger())                    
                    return true;
               begins.top()++;
               begins.push(x->getList().begin());
               ends.push(x->getList().end());
           }
       }        
return false;
   }
private:    
        stack<vector<NestedInteger>::iterator> begins, ends;
};

结果:124ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值