题目1
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node { int val; Node *left; Node *right; Node *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
示例:
输入:{"$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} 输出:{"$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} 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。
提示:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
思路及代码
常量级额外空间,就说明只能边遍历边设置next,于是做一下判断然后递归即可。
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/
class Solution {
public:
Node* connect(Node* root) {
if(root == NULL){
return root;
}
if(root->next == NULL && root->right != NULL){
root->right->next = NULL;
}
if(root->left != NULL){
root->left->next = root->right;
}
if(root->right != NULL && root->next != NULL){
root->right->next = root->next->left;
}
if(root->left != NULL){
connect(root->left);
connect(root->right);
}
return root;
}
};
题目2
在MATLAB中,有一个非常有用的函数 reshape
,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据。
给出一个由二维数组表示的矩阵,以及两个正整数r
和c
,分别表示想要的重构的矩阵的行数和列数。
重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充。
如果具有给定参数的reshape
操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
示例 1:
输入: nums = [[1,2], [3,4]] r = 1, c = 4 输出: [[1,2,3,4]] 解释: 行遍历nums的结果是 [1,2,3,4]。新的矩阵是 1 * 4 矩阵, 用之前的元素值一行一行填充新矩阵。
示例 2:
输入: nums = [[1,2], [3,4]] r = 2, c = 4 输出: [[1,2], [3,4]] 解释: 没有办法将 2 * 2 矩阵转化为 2 * 4 矩阵。 所以输出原矩阵。
注意:
- 给定矩阵的宽和高范围在 [1, 100]。
- 给定的 r 和 c 都是正数。
思路及代码
class Solution {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
vector<int> num;
vector<vector<int>> ret;
if(nums.size() * nums[0].size() != r*c){
return nums;
}
for(int i = 0;i < nums.size();i++){
for(int j = 0;j < nums[0].size();j++){
num.push_back(nums[i][j]);
}
}
vector<int> hang;
int k = 0;
for(int i = 0;i < r;i++){
for(int j = 0;j < c;j++){
hang.push_back(num[k]);
k++;
}
ret.push_back(hang);
hang.clear();
}
return ret;
}
};
题目3
设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。
注意: 允许出现重复元素。
insert(val)
:向集合中插入元素 val。remove(val)
:当 val 存在时,从集合中移除一个 val。getRandom
:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
示例:
// 初始化一个空的集合。 RandomizedCollection collection = new RandomizedCollection(); // 向集合中插入 1 。返回 true 表示集合不包含 1 。 collection.insert(1); // 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。 collection.insert(1); // 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。 collection.insert(2); // getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。 collection.getRandom(); // 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。 collection.remove(1); // getRandom 应有相同概率返回 1 和 2 。 collection.getRandom();
思路及代码
直接参见博客思路:https://blog.csdn.net/qq_22379931/article/details/89409762
class RandomizedCollection {
public:
unordered_map<int, unordered_set<int>> m_map;
vector<int> data;
/** Initialize your data structure here. */
RandomizedCollection() {
m_map.clear();
data.clear();
}
/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
bool insert(int val) {
m_map[val].insert(data.size());//插入下标
data.push_back(val);
return m_map[val].size() == 1;
}
/** Removes a value from the collection. Returns true if the collection contained the specified element. */
bool remove(int val) {
if (m_map[val].size() == 0)
{
return false;
}
//val所对应的unorder_map的初始下标
int index = *m_map[val].begin();
//把该初始下标在unorder_map中删掉
m_map[val].erase(index);
//要删除的不是data的最后一个元素
if (index != data.size() - 1) {
int lastEle = data.back();
//vector data中把最后一个元素赋值给要删除的元素
data[index] = lastEle;
//在map中删除最后一个元素的最后一个索引
m_map[lastEle].erase(data.size()-1);
//替换后,就把替换以后的索引在插到这个部分来
m_map[lastEle].insert(index);
}
data.pop_back();
return true;
}
/** Get a random element from the collection. */
int getRandom() {
int key = rand()%data.size();
return data[key];
}
};
/**
* Your RandomizedCollection object will be instantiated and called as such:
* RandomizedCollection* obj = new RandomizedCollection();
* bool param_1 = obj->insert(val);
* bool param_2 = obj->remove(val);
* int param_3 = obj->getRandom();
*/