leetcode第 381 场周赛最后一题 差分,对称的处理

这篇具有很好参考价值的文章主要介绍了leetcode第 381 场周赛最后一题 差分,对称的处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第 381 场周赛 - 力扣(LeetCode)最后一题3017. 按距离统计房屋对数目 II - 力扣(LeetCode)

dijkstra超时了,看了灵神的解题方法力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台,其实是差分优化的暴力统计

灵神说的“撤销操作”,就是先不加那条xy新路,统计出所有距离对数,然后再加上那条路做修改。做修改需要推一下变短的位置。

灵神封装写的特别好,这道题不封装一下,有问题改起来很麻烦。

目录

统计原始距离对数:

找规律:

灵神暴力左右:

差分:

做修改:

第一种:

第二种:

关于小于区间右端点(x+y)/2:(等于过不了)

当 x==y 及x == y+1时没有缩短任何距离。不需要操作

参考代码:


统计原始距离对数:

这里说两种方法,第一种是自己想的找规律(其实踩坑了,没弄好差分),第二种就是灵神暴力,时间复杂度是相同的O(n)

找规律:

分别对奇数和偶数找一下:

第一行1 2 3 4 5五个数是题目里的房屋,左边第一列是距离 t,表中的则是与这个房屋距离为t的房屋数。

我们暴力完成这个表。

比如第一行,对1来说距离为1的只有2一个,所以是1;对2来说距离为1的是1和3,即两个。

会发现每一行会比前一行少2,而第一行也是“1 2 2 .. 2 2 1”可以列式算出来,所以可以距离为1到n的房屋对数数组(我们要返回的数组)给初始化。

        //      1 2 3 4 5
        //1:    1 2 2 2 1   //2就算最多啦
        //2:    1 1 2 1 1   //-2
        //3:    1 1 0 1 1   //-2
        //4:    1 0 0 0 1   //-2
        //5:    0 0 0 0 0   //-2 这个要减成0

        //      1 2 3 4 5 6
        //1:    1 2 2 2 2 1
        //2:    1 1 2 2 1 1     //-2
        //3:    1 1 1 1 1 1     //-2
        //4:    1 1 0 0 1 1     //-2
        //5:    1 0 0 0 0 1     //-2
        //6:    0 0 0 0 0 0     //-2

注意:

房屋数为n的情况下,不存在距离为n的房屋对(最大也是1和n之间差n-1),所以返回数组最后一位必定是0.

灵神暴力左右:

对于房屋 i ,距离为1的就是 i-1 和 i+1 ,距离为2的就是 i-2 和 i+2 ,......

一直到两边,可得左侧距离最大为i-1,右侧为n-i,

所以距离为 1 ~ i -1  的都要加一对,距离为 1 ~ n - i 的也都要加一对

差分:

而我们正好用的是差分数组。差分就是第一位为初始值,后面的都表示和前一位相差的值。对这种连续的情况,用差分是秒算的。

做修改:

首先看情况,其实就四种会变短,而这四种是对称的,也就是说其实就两种情况。

我们 i 为始点,j为终点,(x,y)为新增的路,我们让x<y。

第一种:

i 在 x左边    i <= x 

只有当 j 在y左右的时候才会缩短距离:

leetcode第 381 场周赛最后一题 差分,对称的处理,力扣周赛,leetcode,算法,差分,对称

j在y左的位置的计算:就是算什么时候走新路更短

 leetcode第 381 场周赛最后一题 差分,对称的处理,力扣周赛,leetcode,算法,差分,对称

偶数的话会有一个点,这个点不走(大于号嘛,不取)

奇数的话本是两点之间,正好向下取整了,如下图的a,中间是正好,所以b可取

leetcode第 381 场周赛最后一题 差分,对称的处理,力扣周赛,leetcode,算法,差分,对称

第二种:

x < i < (x+y)/2      剩下的区间就是对称的

leetcode第 381 场周赛最后一题 差分,对称的处理,力扣周赛,leetcode,算法,差分,对称

第二种的y左这个j的计算

leetcode第 381 场周赛最后一题 差分,对称的处理,力扣周赛,leetcode,算法,差分,对称

关于小于区间右端点(x+y)/2:(等于过不了)

这个短点也没有缩短的:

奇数情况        x -  - i - - y       很明显i到x和y一样远

偶数情况        x - i - - y          i直接到y为3,i到x再到y为2+1 == 3

所以<(x+y)/2

——————

当 x==y 及x == y+1时没有缩短任何距离。不需要操作

参考代码:

灵神那个写的好,我没封装。不过对称的处理可以看看,处理是类似的。

他用函数会还原,我是用个if 还原的,然而if条件有关于对称用的值的,所以后面可能进不去,还原失败。文章来源地址https://www.toymoban.com/news/detail-817130.html

class Solution {
#define ll long long
    vector<ll>ans;
    void add(int l, int r, int v)
    {
        if(l>r)return;
        ans[l] += v;
        ans[r + 1] -= v;
    }
public:
    vector<long long> countOfPairs(int n, int x, int y)
    {
        if (x>y)swap(x, y);

        ans = vector<ll>(n + 2);
        // ans[1] = n + n - 2;
        // for (int i = 2; i <= n - 1; i++)
        // {
        //     ans[i] = -2;
        // }
        //

            for (int k = 1; k <= n; k++)
            {
                int i = k,orx = x,ory = y;
                add(1, i - 1, 1);
                add(1, n - i, 1);
                if (y - x < 2)continue;
                if (k > (orx + ory + 1) / 2)
                {
                    i = n + 1 - k;
                    x = n + 1 - ory;
                    y = n + 1 - orx;
                }
                if (i <= x)
                {
                    //1.j>=y
                    add(y - i, n - i,-1);
                    
                    //add(x-i+1,x-i+1+n-y, 1);没有想用“缩短的距离”
                    int dec = y - x - 1;//比如 2 3 连完还是1,缩短了0,3-2-1
                    add(y - i - dec, n - i - dec, 1);

                    //2.x<j<y       i    x     j y
                    //只管能短的,即:j-i > x-i + 1 + y-j
                    //              2j > x+y+1
                    //               j > (x+y+1)/2
                    //j==(x+y+1)/2+1
                    int j = (x + y + 1) / 2 + 1;
                    //j到y-1
                    add(j-i,y-i-1,-1);

                    add(x - i + 2, x-i + 1 + y-j, 1);
                    //3.j<=x不用管
                }
                else if (i < (x + y) / 2)// x - i - y 与 x - i - - y 都是不起作用,不需等于
                {                        //等于的话
                    //y右:
                    add(y-i,n-i,-1);
                    int dec = y - i - (i - x + 1);
                    add(y - i-dec, n - i-dec, 1);

                    //y左:
                    //j-i>i-x+1+y-j
                    //2j>2i-x+1+y
                    //j>(2i-x+1+y)/2
                    int j = i + (- x + 1+ y) / 2 + 1;
                    add(j-i,y-1-i,-1);
                    add(i - x +2, i - x + y - j + 1,1);
                }

                if (k > (orx + ory + 1) / 2)
                {
                    x = orx;
                    y = ory;
                }
            }
        vector<ll>ret(n);
        ll sum_d = 0;
        for (int i = 0; i < n; i++)
        {
            sum_d += ans[i+1];
            ret[i] = sum_d;
        }
        return ret;
    }
};

到了这里,关于leetcode第 381 场周赛最后一题 差分,对称的处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [LeetCode周赛复盘] 第 353 场周赛20230709

    感觉有奖品大家都来了。 T1 数学。 T2 dp。 T3 dp。 T4 差分/BIT RUPQ。 6451. 找出最大的可达成数字 1. 题目描述 2. 思路分析 为了使x num在t步内相同,需要相向而行,每步最大缩短距离是2,那么t步距离是2t。 3. 代码实现 6899. 达到末尾下标所需的最大跳跃次数 1. 题目描述 2. 思路分

    2024年02月15日
    浏览(21)
  • [LeetCode周赛复盘] 第 348场周赛20230604

    这场可惜了。 T1 模拟。 T2 模拟。 T3 倒序计算。 T4 同时限制上下界的数位DP。 6462. 最小化字符串长度 1. 题目描述 2. 思路分析 题意仔细想一下就会发现,其实会将每个字符仅留1个。 3. 代码实现 6424. 半有序排列 1. 题目描述 2. 思路分析 由于只能相邻交换来移动,因此每次只能

    2024年02月08日
    浏览(30)
  • LeetCode第347场周赛

    2023.5.28LeetCode第347场周赛 从最后一位开始遍历,为0则跳过 暴力模拟 对于每个 s[i] != s[i - 1] ,要使其相等 有两种选择,翻转前 i 个,或者翻转后 n - i 个,选择代价最小的方案 动态规划 从小到大枚举所有值,每个值一定是从更小的数转移而来 定义动态规划数组f, f[i][j] 表示

    2024年02月06日
    浏览(65)
  • LeetCode第343场周赛

    2023.4.30LeetCode第343场周赛 根据题意模拟 使用哈希表记录每个数出现的位置,再用m+n个集合记录每一行和每一列被涂满的格子数,若某行或某列全部被涂满则返回答案 BFS 首先将距离大于两点的曼哈顿距离的特殊路径去掉 每个点考虑经过每个特殊路径到达,分成两段,一段是当

    2024年02月02日
    浏览(30)
  • LeetCode第354场周赛

    给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 对 nums 中的元素 nums[i] 而言,如果 n 能够被 i 整除,即 n % i == 0 ,则认为 num[i] 是一个 特殊元素 。 返回 nums 中所有 特殊元素 的 平方和 。 直接模拟就好了 给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。 在一

    2024年02月16日
    浏览(32)
  • leetcode 第360场周赛

    好久没参加leetcode周赛了,比赛时间都从两小时变成了一个半小时。这次周赛由两道签到题和两道中等难度题组成,严格来说最后一道的难度也可以视为hard,但是只要想到正确的思路,编码还是比较容易的。 比赛链接:leetcode 第 360 场周赛 题目描述 给你一个长度为 n 的字符串

    2024年02月11日
    浏览(28)
  • leetcode第 357/358 场周赛

    可能别人有更好的解法,我这写法是不断往线段树中插入数值,每次先插入nums[i-x],然后搜索(1到i)中的最大值和(i到max)中的最小值去更新ans。 看了看别人题解,直接用set写是真的牛。自己还是见识短浅了。 暴力乱搞,考虑两种极端情况,一种无脑选profit大的,一种优先选

    2024年02月12日
    浏览(30)
  • leetcode第354场周赛补题

    6889. 特殊元素平方和 - 力扣(LeetCode) 思路:模拟 6929. 数组的最大美丽值 - 力扣(LeetCode) 思路:排序+双指针 6927. 合法分割的最小下标 - 力扣(LeetCode) 思路:哈希+枚举 6924. 最长合法子字符串的长度 - 力扣(LeetCode) 思路:哈希+双指针

    2024年02月16日
    浏览(26)
  • Leetcode 第 365 场周赛题解

    思路 暴力。 代码 复杂度分析 时间复杂度:O(n 3 ),其中 n 是数组 nums 的长度。 空间复杂度:O(1)。 思路 枚举 k,我们需要知道 k 左边 nums[i]−nums[j] 的最大值。 使用 pre_max 维护 k 之前的 nums[i] 的最大值,使用 max_diff 维护 nums[i]−nums[j] 的最大值。 每次遍历一个 nums[i],都更新

    2024年02月07日
    浏览(24)
  • LeetCode 第 388 场周赛个人题解

    目录 100233. 重新分装苹果 原题链接 思路分析 AC代码 100247. 幸福值最大化的选择方案 原题链接 思路分析 AC代码 100251. 数组中的最短非公共子字符串 原题链接 思路分析 AC代码 100216. K 个不相交子数组的最大能量值 原题链接 思路分析 AC代码 100233. 重新分装苹果 直接模拟 降序排

    2024年03月15日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包