【模拟面试】#7 翻转图像 按既定顺序创建目标数组 在线选举

本文探讨了三个具体的算法问题:水平翻转并反转二进制矩阵、根据指定索引构建目标数组以及选举中主导候选人的实时查询。通过详细的代码实现和思路解析,为读者提供了深入理解算法设计的机会。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目1

给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。

水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]

反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。例如,反转 [0, 1, 1] 的结果是 [1, 0, 0]

示例 1:

输入: [[1,1,0],[1,0,1],[0,0,0]]
输出: [[1,0,0],[0,1,0],[1,1,1]]
解释: 首先翻转每一行: [[0,1,1],[1,0,1],[0,0,0]];
     然后反转图片: [[1,0,0],[0,1,0],[1,1,1]]

示例 2:

输入: [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]]
输出: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]
解释: 首先翻转每一行: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]];
     然后反转图片: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]

说明:

  • 1 <= A.length = A[0].length <= 20
  • 0 <= A[i][j] <= 1

思路及代码

reverse:翻转一行

class Solution {
public:
    vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A) {
        int h = A.size();
        
        for(int i = 0;i < h;i++){
            reverse(A[i].begin(),A[i].end());
        }

        int w = A[0].size();

        for(int i = 0;i < h;i++){
            for(int j = 0;j < w;j++){
                A[i][j] = A[i][j] ^ 1;
            }
        }

        return A;
    }
};

题目2

给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组:

  • 目标数组 target 最初为空。
  • 按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。
  • 重复上一步,直到在 nums 和 index 中都没有要读取的元素。

请你返回目标数组。

题目保证数字插入位置总是存在。

 

示例 1:

输入:nums = [0,1,2,3,4], index = [0,1,2,2,1]
输出:[0,4,1,3,2]
解释:
nums       index     target
0            0        [0]
1            1        [0,1]
2            2        [0,1,2]
3            2        [0,1,3,2]
4            1        [0,4,1,3,2]

示例 2:

输入:nums = [1,2,3,4,0], index = [0,1,2,3,0]
输出:[0,1,2,3,4]
解释:
nums       index     target
1            0        [1]
2            1        [1,2]
3            2        [1,2,3]
4            3        [1,2,3,4]
0            0        [0,1,2,3,4]

示例 3:

输入:nums = [1], index = [0]
输出:[1]

 

提示:

  • 1 <= nums.length, index.length <= 100
  • nums.length == index.length
  • 0 <= nums[i] <= 100
  • 0 <= index[i] <= i

思路及代码

直接用vector提供的insert方法。

class Solution {
public:
    vector<int> createTargetArray(vector<int>& nums, vector<int>& index) {
        vector<int> ret;

        int len = nums.size();

        ret.push_back(nums[0]);

        for(int i = 1;i < len;i++){
            ret.insert(ret.begin() + index[i],nums[i]);
        }

        return ret;
    }
};

题目3

在选举中,第 i 张票是在时间为 times[i] 时投给 persons[i] 的。

现在,我们想要实现下面的查询函数: TopVotedCandidate.q(int t) 将返回在 t 时刻主导选举的候选人的编号。

在 t 时刻投出的选票也将被计入我们的查询之中。在平局的情况下,最近获得投票的候选人将会获胜。

示例:

输入:["TopVotedCandidate","q","q","q","q","q","q"], [[[0,1,1,0,0,1,0],[0,5,10,15,20,25,30]],[3],[12],[25],[15],[24],[8]]
输出:[null,0,1,1,0,0,1]
解释:
时间为 3,票数分布情况是 [0],编号为 0 的候选人领先。
时间为 12,票数分布情况是 [0,1,1],编号为 1 的候选人领先。
时间为 25,票数分布情况是 [0,1,1,0,0,1],编号为 1 的候选人领先(因为最近的投票结果是平局)。
在时间 15、24 和 8 处继续执行 3 个查询。

提示:

  1. 1 <= persons.length = times.length <= 5000
  2. 0 <= persons[i] <= persons.length
  3. times 是严格递增的数组,所有元素都在 [0, 10^9] 范围中。
  4. 每个测试用例最多调用 10000 次 TopVotedCandidate.q
  5. TopVotedCandidate.q(int t) 被调用时总是满足 t >= times[0]

思路及代码

记录:时间点数组、时间点对应的最大票获得者数组、人对应票获得者数组、最大获得者、最大票数。

查找的时候用二分法来提高速度。

class TopVotedCandidate {
public:

    int time[5001];
    int len;
    map<int,int> time_people;
    map<int,int> people_ticket;
    int maxpeople;
    int maxticket;


    TopVotedCandidate(vector<int>& persons, vector<int>& times) {
        maxpeople = 0;
        maxticket = 0;
        len = times.size();
        
        for(int i = 0;i < len;i++){
            people_ticket[persons[i]]++;
            
            if(people_ticket[persons[i]] >= maxticket){
                maxticket = people_ticket[persons[i]];
                maxpeople = persons[i];
            }

            time_people[times[i]] = maxpeople;
            time[i] = times[i];
        }
    }
    
    int q(int t) {
        int left = 0;
        int right = len-1;

        while(left<=right && left<len){
            int mid = (left+right)/2;
        
            if(t < time[mid]){
                right = mid-1;
            }else if(t > time[mid]){
                left = mid+1;
            }else if(t == time[mid]){
                return time_people[t];
            }
        }
        return time_people[time[left-1]];
    }
};

/**
 * Your TopVotedCandidate object will be instantiated and called as such:
 * TopVotedCandidate* obj = new TopVotedCandidate(persons, times);
 * int param_1 = obj->q(t);
 */

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值