jjzjj

代码随想录算法训练营第二天| 977.有序数组的平方、 209.长度最小的子数组、59.螺旋矩阵II

Aragakan 2023-07-23 原文

977.有序数组的平方

思路:数组是非递减的,因此数组的单调性呈V形,数组平方的最大值肯定出现在边界,所以我们可以对边界进行检查,将平方数大的插入新的数组的尾部。

问题:
可能受到了移除元素那题的影响,刚开始一直把自己局限在空间复杂度O(1)且时间复杂度O(N)的方法(即只在原数组进行操作),最后才发现不可行浪费时间。
算法完成过程中可能是写迷糊了,犯了很多低级错误,包括比较条件没用平方,进行操作后两个指针没有更新。说明在检查过程没有行程统一的习惯。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n = nums.size();
        int i = 0;
        int j = n - 1;
        vector<int>result(n,0);
        while (i <= j){
            if (nums[i] * nums[i] <= nums[j] * nums[j]) {
                result[--n] = nums[j] * nums[j];
                --j;
            }
            else if (nums[i] * nums[i] > nums[j] * nums[j]){
                result[--n] = nums[i] * nums[i];
                ++i;
            }
        }
        return result;
    }
};

209. 长度最小的子数组

思路

题目要求是连续子数组,所以可以考虑用滑动窗口解决。通过增长和缩短窗口区间来实现符合要求的连续数组的遍历。不断增长让窗口符合条件(sum >= target)然后缩短窗口破坏条件使得(sum < target),一旦不满足条件继续增长。要仔细考虑边界条件和特殊情况。

问题

忘了考虑特殊情况!当tail等于n且sum不超过target时就可以结束循环,但如果整个数组加起来都没超过target,相当于在循环过程中没进行min_len的更新,那么会返回INT_MAX,所以要特殊处理。

class Solution {
public:
    //题目要求是连续子数组,所以可以通过增长缩短区间
    //sum超过target就从头部缩短,没超过就加长尾部
    //记录最小数组长度
    //[head, tail)
    int minSubArrayLen(int target, vector<int>& nums) {
        int min_len = INT_MAX;
        int head = 0;
        int tail = 0;
        int sum = 0;
        //尾部正常访问数据
        while (tail <= nums.size()){
            if (sum < target) {
                if (tail == nums.size()) {
                    break;
                }
                sum += nums[tail++];
            }
            if (sum >= target){
                if (tail - head < min_len){
                    min_len = tail - head;
                }
                sum -= nums[head++];
            }
        }
        if (min_len == INT_MAX) return 0;
        return min_len;
    }
};

代码优化

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int min_len = nums.size() + 1;
        int head = 0;
        int sum = 0;
        // Use a for loop for clarity and to avoid off-by-one errors.
        for (int tail = 0; tail < nums.size(); tail++) {
            sum += nums[tail];
            while (sum >= target) {
                int len = tail - head + 1;
                if (len < min_len) {
                    min_len = len;
                }
                sum -= nums[head++];
            }
        }
        return (min_len > nums.size()) ? 0 : min_len;
    }
};

59. 螺旋矩阵 II

思路:顺时针由四个循环的方向组成,可以考虑用取余实现方向的转换,方向转换的边界条件判断:

  1. 超出数组的边界条件
  2. 下一步要走的位置已经被走过,即 != 初始值

每次走一步(赋值),并且确定下一步的位置(方向的判断和转换)

问题:小错误,0,1,2,3是对4取余,不是对3取余

class Solution {
public:
    // +c, +r, -c, -r
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result (n, vector<int>(n, -1));
        int dir = 0;
        int i = 0;
        int j = 0;
        int p = 0;
        for (int k = 1; k <= n * n; ++k) {
            result[i][j] = k;
            if (dir == 0){
                if (j + 1 >= n) turn_dir(dir);
                else if (result[i][j+1] != -1) turn_dir(dir);
                update_ij_by_dir(i, j, dir);
            }
            else if (dir == 1) {
                if (i + 1 >= n) turn_dir(dir);
                else if (result[i+1][j] != -1) turn_dir(dir);
                update_ij_by_dir(i, j, dir);
            }
            else if (dir == 2){
                if (j - 1 < 0) turn_dir(dir);
                else if (result[i][j-1] != -1) turn_dir(dir);
                update_ij_by_dir(i, j, dir);
            }
            else if (dir == 3){
                if (i - 1 < 0) turn_dir(dir);
                else if (result[i - 1][j] != -1) turn_dir(dir);
                update_ij_by_dir(i, j, dir);
            }
        }
        return result;
    }
    void update_ij_by_dir(int& i, int& j, int dir){
        if (dir == 0) ++j;
        else if (dir == 1) ++i;
        else if (dir == 2) --j;
        else if (dir == 3) --i;
    }
    void turn_dir(int& dir){
        dir = (dir + 1) % 4;
    }
};


有关代码随想录算法训练营第二天| 977.有序数组的平方、 209.长度最小的子数组、59.螺旋矩阵II的更多相关文章

  1. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  5. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  6. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  7. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  8. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  9. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  10. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

随机推荐