美文网首页
2020-02-05 刷题2(数组)

2020-02-05 刷题2(数组)

作者: nowherespyfly | 来源:发表于2020-02-06 11:41 被阅读0次

189 旋转数组

数组整体移位的题目。
最简单的就是,用另一个数组来暂时存放,时间复杂度O(n), 空间复杂度O(n).
之前离散数学里,学过一种原地操作的解法,比如:
[1, 2, 3, 4, 5, 6], k=2
则可以构成两个环,分别为:[1,3, 5], [2,4,5];
在每个环内,设置一个变量cur_start来记录环起点,每次将环中前一个元素复制到后一个元素中,如果后一个元素的下标等于环起点,则这个环全部移位完成;将cur_start加1来操作下一个环。设置一个变量c来记录完成移位的元素个数。
时间复杂度:O(n)
空间复杂度:O(1)
代码:

时间:98.03%, 空间:5.04%
class Solution {
public:
void rotate(vector<int>& nums, int k) {
    int a_len = nums.size();
    k = k % a_len;
    if (k == 0)
        return;
    int c = 0;
    int cur_start = 0;
    int s = 0, t;   // start_pos, end_pos
    int last = nums[0], tmp;   // tmp var to store end_pos element
    while(c < a_len){
        t = (s + k) % a_len;
        
        // use last element to fill in current position
        tmp = nums[t];
        nums[t] = last;
        last = tmp;
        
        if(t == cur_start){
            cur_start++;
            s = cur_start;
            last = nums[s];
        }
        
        else s = t;
        c++;
    }
}
};

还有另一种解法也很巧妙,经过步长为k的移位后,后面k个元素被反转到了前面,剩下的前面的元素留在了后面。


官方题解

经过三次翻转,也可以使得各个元素归位。


122 买卖股票的最佳时机II

一定要注意边界条件,不控制边界条件可能会runtime error的

一开始想了一种动态规划的解法,将i买入,j卖出的最大利润记做P(i,j),然后写出递推公式。但是这种做法的时间复杂度是O(n^3),运行到最后一个测试样例就超时了。

后来分析问题发现,对于a1, a2, a3, a4这样的序列,如果a1<a2, a1<a4, a3<a4, a3<a2,也就是这四个数第二和第三个是局部最大值和局部最小值,则a1买入,a4卖出的利润一定小于a1买入a2卖出a3买入a4再卖出。也就是说,对于一个序列,局部最小值一定是可以买入的,局部最大值一定是可以卖出的,这样至少不会使得最终的总利润变低。

因此,最后的解法是,在数组最左侧和最右侧分别设置一个最大值和最小值作为哨兵,从左到右遍历数组,找到局部最小值就买入,找到局部最大值就卖出。

即使这样,还有一个问题,如果连续几天的股票价格都一样,就很难定义局部最值了。因此,首先遍历一遍数组,将连续的重复值去掉,然后再开始股票买卖。这里,去重用的是双指针,也是一个非常巧妙的做法,可以参考26. 删除排序数组中的重复项
时间复杂度:O(n)
空间复杂度: O(1)
代码:

时间:70.09%, 内存:5%
class Solution {
public:
int maxProfit(vector<int>& prices) {
    int vec_len = prices.size();
    // remove continuous repeated element
    int p = 0, q = 1;
    for(;q < vec_len; q++){
        if (prices[q] != prices[p]){
            p++;
            prices[p] = prices[q];
        }
    }
    vec_len = p + 1;
    if (vec_len <= 1)
        return 0;
    
    // set guardance
    if (vec_len == prices.size())
        prices.push_back(0);
    else prices[vec_len] = 0;
    prices.insert(prices.begin(), 2147483647);
    
    int profit = 0;
    int in, out;
    bool is_out = false;
    for(int i = 1; i <= vec_len; i++){
        if (!is_out){
            // find local min
            if (prices[i] < prices[i-1] && prices[i] < prices[i+1]){
                in = prices[i];
                is_out = true;
            }
        }
        else{
            // find local max
            if (prices[i] > prices[i-1] && prices[i] > prices[i+1]) {
                out = prices[i];
                profit += (out - in);
                is_out = false;
            }
        }
    }
    return profit;
}
};

另一种解法,是不需要提前去掉连续重复的元素,只要通过while循环,来找到峰值和谷值,只要将while循环中第二个判断条件设为小于等于(或大于等于),就可以达到排除相等元素的作用。

time: 97.64%, memory: 42.59%
class Solution {
public:
int maxProfit(vector<int>& prices) {
    int vec_len = prices.size();
    if (vec_len <= 1)
        return 0;

    int profit = 0;
    int valley = prices[0], peak = prices[0];
    int idx = 0;
    while(idx < vec_len){
        // find valley
        while(idx < vec_len - 1 && prices[idx + 1] <= prices[idx]){
            idx++;
        }
        valley = prices[idx];
        idx++;
        if (idx >= vec_len)  // 不加入这一判断会溢出
            break;
        // find peak
        while(idx < vec_len - 1 && prices[idx + 1] >= prices[idx]){
            idx++;
        }
        peak = prices[idx];
        idx++;
        if (peak > valley)
            profit += (peak - valley);
    }
    return profit;
}
};

相关文章

  • 2020-02-05 刷题2(数组)

    189 旋转数组 数组整体移位的题目。最简单的就是,用另一个数组来暂时存放,时间复杂度O(n), 空间复杂度O(n...

  • 刷题-数组专项

    数组 二维数组中的查找题目描述:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每...

  • 2020-06-30 刷题2(数组)

    1. 判断字符是否唯一(面试题01.01) 用数组 2. 判定是否为字符串重排 还是用数组。

  • 2020-02-07 刷题 2(数组)

    66 加一 思路很简单,从后向前扫描,如果当前位小于9,就加一然后退出循环,否则置零继续向前循环。最后判断一下第一...

  • 2020-02-08 刷题 2(数组)

    36 有效的数独 由于二维数组一共只有81个数,所以基本都可以保证常数时间复杂度和常数空间复杂度。官方题解里,每行...

  • 数组-Python刷题笔记

    二维数组中的查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上...

  • leetcode刷题之数组

    leetcode刷题,使用python 1, 两数之和—— 0001 数组给定一个整数数组 nums 和一个整数...

  • [数组]442. Find All Duplicates in

    标签(空格分隔): 数组 leetcode 刷题 题目链接 给定一个数组,1≤a[i]≤n(n =数组的大小),里...

  • Java全排列递归算法

    刷题!刷题!发现对于数组元素的全排列很多题目都有涉及到,所以详细研究一下对一个数组进行全排列,我们可以这样考虑,我...

  • leecode刷题(3)-- 旋转数组

    leecode刷题(3)-- 旋转数组 旋转数组 给定一个数组,将数组中的元素向右移动 K 个位置,其中 K 是非...

网友评论

      本文标题:2020-02-05 刷题2(数组)

      本文链接:https://www.haomeiwen.com/subject/kbwjxhtx.html