当前位置: 首页 > article >正文

⭐LeetCode周赛 3468. 可行数组的数目——暴力与数学⭐

⭐LeetCode周赛 3468. 可行数组的数目——暴力与数学⭐

在这里插入图片描述

示例 1:
输入:original = [1,2,3,4], bounds = [[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:
可能的数组为:
[1, 2, 3, 4]
[2, 3, 4, 5]

示例 2:
输入:original = [1,2,3,4], bounds = [[1,10],[2,9],[3,8],[4,7]]
输出:4
解释:
可能的数组为:
[1, 2, 3, 4]
[2, 3, 4, 5]
[3, 4, 5, 6]
[4, 5, 6, 7]

提示:
2 <= n == original.length <= 105
1 <= original[i] <= 109
bounds.length == n
bounds[i].length == 2
1 <= bounds[i][0] <= bounds[i][1] <= 109

题解:

暴力法+数学法 具体见代码注释

代码:

// 暴力  超时
// 思路为一旦copy[0]确定 则copy数组即确定 因各元素间距由original可提前算出
// 故仅对copy[0]的值进行模拟 从u0遍历到v0 
// 同时判断按照上述情况得到的copy数组如copy[1] copy[2]等是否满足他们的ui和vi限制即可
// 即由于各元素间距固定 故多个需要遍历的变量可以变为进遍历单一变量copy[0] 再加以对所有可能的数组进行验证即可
class Solution1 {
    public int countArrays(int[] original, int[][] bounds) {
        int len = original.length;
        int res = 0;
        int[] next_len = new int[len];
        
        for(int i=1;i<len;i++){
            next_len[i] = original[i] - original[i-1];
        }

        int L = bounds[0][0];
        int R = bounds[0][1];
        while(L <= R){
            int[] temp = new int[len];
            temp[0] = L;
            for(int i=1;i<len;i++){
                temp[i] = temp[i-1] + next_len[i];
            }

            boolean flag = true;
            for(int i=1;i<bounds.length;i++){
                if(temp[i] >= bounds[i][0] && temp[i] <= bounds[i][1]){
                    continue;
                }
                else{
                    flag = false;
                    break;
                }
            }
            if(flag){
               res++; 
            }
            L++;
        }
        return res;
    }
}

// 数学 算出copy[0]的实际可取值范围即为关键
// 公式化简可知 copy[i] = copy[0] + di 即copy的任一元素均可由copy[0]推演得到
// 故 ui <= copy[i] <= vi ---> ui-di <= copy[0] <= vi-di
// 则上述式子即为copy[0]的取值范围限制 对所有情况的i均算出 取交集即可
class Solution {
    public int countArrays(int[] original, int[][] bounds) {
        int len = original.length;
        // 先定义copy[0]取值范围为本身的限制 即此时为最宽泛情况
        // 即先进行u0-d0 <= copy[0] <= v0-d0第一层限制
        int L = bounds[0][0];
        int R = bounds[0][1];

        // 后面遍历bounds 依次得到ui和vi 对copy[0]区间进行缩小
        for(int i=1;i<len;i++){
            int di = original[i] - original[0];
            int ui = bounds[i][0];
            int vi = bounds[i][1];
            L = Math.max(L,ui-di);
            R = Math.min(R,vi-di);
        }

        // 若最后得到为负 则代表无符合题目条件的数组 故返回0
        return R-L+1 > 0 ? R-L+1 : 0;
    }
}

结果:

在这里插入图片描述


http://www.kler.cn/a/580332.html

相关文章:

  • SpringBoot 如何调用 WebService 接口
  • C#主流日志库深度对比:NLog、log4net与Serilog如何选择?
  • 在vs中无法用QtDesigner打开ui文件的解决方法
  • BGP(三)联盟、反射器
  • 区块链概述及比特币工作原理
  • DeepSeek开源Day5:3FSsmallpond技术详解
  • 最大括号深度
  • 【面试】Kafka
  • 三个一行的多选框组
  • 破局企业AI落地难题!迅易科技DeepSeek私有化部署全场景解决方案
  • Swagger笔记
  • C#中的【Obsolete】属性Attribute
  • MySQL初阶 | 库的操作
  • PostgreSQL 的登陆方式(本地和远程)
  • 《人月神话》:软件工程的成本寓言与生存法则
  • postgresql使用mysql_fdw连接mysql
  • 大白话如何使用 CSS 实现响应式布局?请列举一些常见的方法。
  • Vue3中如何实现单页应用(SPA)导航操作
  • HTML中的块元素与行内元素
  • P8700 [蓝桥杯 2019 国 B] 解谜游戏--string与cstring、memset()介绍