日练三题,冰冻三尺非一日之寒。
今日题目: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