【模拟面试】#8 填充每个节点的下一个右侧节点指针 重塑矩阵 O(1) 时间插入、删除和获取随机元素 - 允许重复

题目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,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据。

给出一个由二维数组表示的矩阵,以及两个正整数rc,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充。

如果具有给定参数的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. 给定矩阵的宽和高范围在 [1, 100]。
  2. 给定的 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) , 执行以下操作的数据结构。

注意: 允许出现重复元素。

  1. insert(val):向集合中插入元素 val。
  2. remove(val):当 val 存在时,从集合中移除一个 val。
  3. 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();
 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值