LeetCode 1470 - 1473

 重新排列数组

 

给出一个数组 nums,数组中一共有 2n 个元素,分为两段,第一段是 x1 ~ xn,第二段是 y1 ~ yn

需要把它重新排列为[x1,y1,x2,y2,...,xn,yn]

示例1:

2、5、1、3、4、7        n = 3

开一个新的数组用来记录最终答案,从 0 ~ n - 1 去遍历一遍,每次把当前循环变量指向的这个数放到数组的最后一个位置,再把它后面的和它配对的一个数(当前指针 + n 的位置上的数) 放在后面,最后把指针往后移动一位. . .

时间复杂度 O( n ),n 的范围为 500

 

class Solution {
public:
    vector<int> shuffle(vector<int>& nums, int n) {
        //定义答案数组
        vector<int> res;
        //从 0 ~ n 循环一遍
        for(int i = 0;i < n;i++ ) {
            //每次把当前第 i 个数放进来
            res.push_back(nums[i]);
            //把 i + n 位置上的数放进来
            res.push_back(nums[i + n]);
        }
        return res;
    }
};

数组中的 k 个最强值

给出一个数组和一个整数 k,定义了数组中两个元素比较大小的方式:先求数组里面的中位数,假设中位数是 m,按照如下方式来比较两个变量的大小,如果|arr[i] - m| != |arr[j] - m|绝对值大的那个更好,如果|arr[i] - m| == |arr[j] - m|数值大的那个更好,返回由数组中最强的 k 个值组成的列表

任何两个元素之间都可以作比较

需要排序

数据范围为 10^5,时间复杂度要控制在 nlogN

中位数的定义:

如果是奇数个数,中位数一定是最中间这个数,如果是偶数个数,中位数是中间偏左的那个数

在 sort 函数中传入自定义的比较方式

输入的数组不一定是有序的,想求中位数的话需要先给它排序

注意 Lambda 表达式中间不能写变量,可以加引用 &

int m;
bool cmp(int a,int b) {
    if(abs(a - m) != abs(b - m)) return abs(a - m) > abs(b - m);
    return a > b;
}
class Solution {
public:
    vector<int> getStrongest(vector<int>& arr, int k) {
        sort(arr.begin(),arr.end());
        m = arr[(arr.size() - 1) / 2];
        sort(arr.begin(),arr.end(),cmp);
        return vector<int>({arr.begin(),arr.begin() + k});
    }
};
class Solution {
public:
    vector<int> getStrongest(vector<int>& arr, int k) {
        sort(arr.begin(),arr.end());
        //中位数用 m 表示
        int m = arr[(arr.size() - 1) / 2];
        //自定义比较函数
        sort(arr.begin(),arr.end(),[&](int a,int b) {
            //绝对值的大小关系 绝对值大的靠前
            if(abs(a - m) != abs(b - m)) return abs(a - m) > abs(b - m);
            //否则数字大的那个数更大
            return a > b;
        });
        //返回前 k 个元素
        return vector<int>({arr.begin(),arr.begin() + k});
    }
};

设计浏览器历史记录

实现一个类,需要维护游览器的历史记录,一共有三种操作:进到某个新页面,退回到某个页面,前进到某个页面,要求实现这三个操作,最开始在根目录 homepage

注意:从当前页跳转访问 url 对应的页面,执行此操作会把浏览历史前进的记录全部删除,一开始前进 n 步,然后回退 n 步,如果在后退中的某一步( m < n ) 跳到了某一个新的页面:会先把之前 前进跳进去的所有页面 (当前后退步骤后面的所有页面) 全部删除,再跳到新的页面,再回退 1 步,前进 1 步,就会发现前进到的页面是新的页面

示例1:

根目录是 LeetCode,先访问 Google,再访问 Facebook,再访问 YouTube,回退一步输出 Facebook,再回退一步输出 Google,再前进一步输出 Facebook,从 Facebook 访问新的页面 LinkedIn会把 Facebook→ YouTube 的分支删除,重新连接到 LinkedIn,再前进一步,由于后面没有页面就把前进当作没有发生过,所以从 LinkedIn 再前进的话 前进不了,还是 LinkedIn,输出 LinkedIn,再回退两格,退到 Google,输出 Google,再回退两格,没有得退了,还是 LeetCode,输出 LeetCode. . .

维护一个 vector,每个元素最多只会被插入一次,删除一次,时间复杂度 O( 1 ),整个算法时间复杂度 O( n )

class BrowserHistory {
public:

    vector<string> records;
    //记录当前位置
    int  cur;

    BrowserHistory(string homepage) {
        //一开始是一个空的 vector 将homepage 插到vector 中
        records.push_back(homepage);
        cur = 0;
    }
    
    void visit(string url) {
        //如果访问一个新页面 需要把当前位置后面的元素都删除
        records.erase(records.begin() + cur + 1,records.end());
        //在最后插入一个新的页面
        records.push_back(url);
        //将当前位置移到下一个位置
        cur ++;
    }
    
    string back(int steps) {
        //如果要退回一个页面 从当前位置移到前一个位置 最多退到 0 
        cur = max(0,cur - steps);
        return records[cur];

    }
    
    string forward(int steps) {
        //如果要往后跳一个页面 从当前位置往后跳到下个页面 最多前进到 (int)records.size() - 1
        cur = min((int)records.size() - 1,cur + steps);
         return records[cur];
    }
};

/**
 * Your BrowserHistory object will be instantiated and called as such:
 * BrowserHistory* obj = new BrowserHistory(homepage);
 * obj->visit(url);
 * string param_2 = obj->back(steps);
 * string param_3 = obj->forward(steps);
 */

粉刷房子 III

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值