首页 > 其他分享 >力扣-1630. 等差子数组

力扣-1630. 等差子数组

时间:2024-06-23 11:09:45浏览次数:26  
标签:1630 nums int 复杂度 力扣 vector 数组 差子 等差数列

1.题目介绍

题目地址(1630. 等差子数组 - 力扣(LeetCode))

https://leetcode.cn/problems/arithmetic-subarrays/

题目描述

如果一个数列由至少两个元素组成,且每两个连续元素之间的差值都相同,那么这个序列就是 等差数列 。更正式地,数列 s 是等差数列,只需要满足:对于每个有效的 is[i+1] - s[i] == s[1] - s[0] 都成立。

例如,下面这些都是 等差数列

1, 3, 5, 7, 9
7, 7, 7, 7
3, -1, -5, -9

下面的数列 不是等差数列

1, 1, 2, 5, 7

给你一个由 n 个整数组成的数组 nums,和两个由 m 个整数组成的数组 lr,后两个数组表示 m 组范围查询,其中第 i 个查询对应范围 [l[i], r[i]] 。所有数组的下标都是 从 0 开始 的。

返回 boolean 元素构成的答案列表 answer 。如果子数组 nums[l[i]], nums[l[i]+1], ... , nums[r[i]] 可以 重新排列 形成 等差数列answer[i] 的值就是 true;否则answer[i] 的值就是 false

 

示例 1:

输入:nums = [4,6,5,9,3,7], l = [0,0,2], r = [2,3,5]
输出:[true,false,true]
解释:
第 0 个查询,对应子数组 [4,6,5] 。可以重新排列为等差数列 [6,5,4] 。
第 1 个查询,对应子数组 [4,6,5,9] 。无法重新排列形成等差数列。
第 2 个查询,对应子数组 [5,9,3,7] 。可以重新排列为等差数列 [3,5,7,9] 。

示例 2:

输入:nums = [-12,-9,-3,-12,-6,15,20,-25,-20,-15,-10], l = [0,1,6,4,8,7], r = [4,4,9,7,9,10]
输出:[false,true,false,false,true,true]

 

提示:

  • n == nums.length
  • m == l.length
  • m == r.length
  • 2 <= n <= 500
  • 1 <= m <= 500
  • 0 <= l[i] < r[i] < n
  • -105 <= nums[i] <= 105

2.题解

2.1暴力枚举

思路

很简单,将数组根据l和r的要求进行拆分排序,然后从头到尾进行遍历,判断是否为等差数组

代码

  • 语言支持:C++

C++ Code:

class Solution {
public:
    vector<bool> checkArithmeticSubarrays(vector<int>& nums, vector<int>& l,vector<int>& r) {
        int m = l.size();
        vector<bool> ans;
        for (int i = 0; i < m; i++) {
            vector<int> subNums(nums.begin() + l[i], nums.begin() + r[i] + 1);
            sort(subNums.begin(), subNums.end());
            int n = subNums.size();
            bool flag = true;
            if (n == 2) {
                ans.push_back(flag);
                continue;
            }
            int sub = subNums[1] - subNums[0];
            for (int j = 2; j < n; j++) {
                if (subNums[j] - subNums[j - 1] != sub) {
                    flag = false;
                    break;
                }
            }
            ans.push_back(flag);
        }
        return ans;
    }
};

复杂度分析

  • 时间复杂度:每个子数组的排序操作为‘o(k log k)’,其中‘k 是子数组的长度。
    由于总共有“m个查询,所以总时间复杂度为”o(m*k log k)”,最坏情况下为\(O(m*n\log n)^{\circ}\)。
  • 空间复杂度:需要额外的空间来存储每个子数组,最坏情况下总空间复杂度为\(\because O(n)^{\circ}\)。

这个解决方案对于给定的限制是高效的,因为 n 和 m 都是 500 以内,排序操作在这个范围内是可以接受的。

2.2 优化(判断等差数列——去除排序步骤)

思路

对于每一个子数组,我们考虑不进行排序判断其是否为等差数列
第一次遍历,确定其最大值,最小值;通过这两个值我们可以判断该数组如果为等差,那么他的公差为

代码

class Solution {
public:
    vector<bool> checkArithmeticSubarrays(vector<int>& nums, vector<int>& l,vector<int>& r) {
        int m = l.size();
        vector<bool> ans;
        for (int i = 0; i < m; i++) {
            int start = l[i], end = r[i];
            int n = end - start + 1; // 子数组总个数 
            int max_value = INT_MIN, min_value = INT_MAX;
            bool isArithmetic = true;
            // 子数组长度为2则必为等差数列
            if(n == 2){
                ans.push_back(isArithmetic);
                continue;
            }
            // 遍历子数组,获得最大值,最小值
            for(int j = start; j <= end; j++){
                max_value = max(max_value, nums[j]);
                min_value = min(min_value, nums[j]);
            }

            // 判断子数组是否为等差数列
            if((max_value - min_value) % (n - 1) != 0){
                isArithmetic = false;
                ans.push_back(isArithmetic);
                continue;
            }
            // 计算公差
            int diff = (max_value - min_value) / (n - 1);
            if(diff == 0){
                ans.push_back(isArithmetic);
                continue;
            }
            vector<bool> visitor(n, false); // 判断是否遇到过该数
            // 遍历数组
            for(int j = start; j <= end; j++){
                if((nums[j] - min_value) % diff != 0){
                    isArithmetic = false;
                    break;
                }
                int pos = (nums[j] - min_value) / diff;
                if(pos >= n || visitor[pos]){
                    isArithmetic = false;
                    break;
                }
                visitor[pos] = true;
            }
            ans.push_back(isArithmetic);
        }
        return ans;
    }
};

复杂度分析

  • 时间复杂度:
    每次查询中,我们需要遍历子数组找最小值和最大值,这需要\(o(k)\)”时间。·然后我们需要再次遍历子数组来判断每个数字的位置,最坏情况下总共需要\(\because o(k)^{\circ}时间\)。
    所以每个查询的时间复杂度是“o(k)”。
    总共有“m个查询,所以总时间复杂度为’o(m*k)’最坏情况下为\(o(n * m)\)
  • 空间复杂度:
    主要是用于记录每个数字位置的布尔数组‘seen’,其大小为子数组的长度,最坏情况下为“o(n)”。总的空间复杂度为 'o(n) 。

标签:1630,nums,int,复杂度,力扣,vector,数组,差子,等差数列
From: https://www.cnblogs.com/trmbh12/p/18263170

相关文章

  • 力扣-三数之和
    文章目录题目题解题目原题链接:三数之和题解思路:一层枚举+双指针publicclassTest{publicstaticList<List<Integer>>threeSum(int[]nums){List<List<Integer>>res=newArrayList<>();if(nums.length<3)returnres;......
  • 力扣-1705. 吃苹果的最大数目
    1.题目介绍题目地址(1705.吃苹果的最大数目-力扣(LeetCode))https://leetcode.cn/problems/maximum-number-of-eaten-apples/题目描述有一棵特殊的苹果树,一连n天,每天都可以长出若干个苹果。在第i天,树上会长出apples[i]个苹果,这些苹果将会在days[i]天后(也就是说,第i+......
  • Leetcode 力扣 125. 验证回文串 (抖音号:708231408)
    如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。字母和数字都属于字母数字字符。给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。示例1:输入:s="Aman,aplan,......
  • Leetcode 力扣 128. 最长连续序列 (抖音号:708231408)
    给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为 O(n) 的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4。示例2:输入:nums=......
  • 力扣-621. 任务调度器
    1.题目题目地址(621.任务调度器-力扣(LeetCode))https://leetcode.cn/problems/task-scheduler/题目描述给你一个用字符数组 tasks表示的CPU需要执行的任务列表,用字母A到Z表示,以及一个冷却时间n。每个周期或时间间隔允许完成一项任务。任务可以按任何顺序完成,但有一......
  • 190.回溯算法:组合(力扣)
    代码随想录(programmercarl.com)一、什么是回溯算法    回溯算法是一种通用的算法设计技巧,特别适用于解决组合、排列、子集等问题。它通过逐步构建解决方案,并在发现部分解决方案无效时撤销(回溯)部分计算,从而寻找所有可能的解决方案。    回溯算法的基本思......
  • 力扣每日一题 6/21 数组
    博客主页:誓则盟约系列专栏:IT竞赛专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞......
  • 力扣-763. 划分字母区间
    题目地址(763.划分字母区间-力扣(LeetCode))https://leetcode.cn/problems/partition-labels/题目描述给你一个字符串s。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是s。返回......
  • 力扣-452. 用最少数量的箭引爆气球
    1.题目介绍题目地址(452.用最少数量的箭引爆气球-力扣(LeetCode))https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/题目描述有一些球形气球贴在一堵用XY平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i]=[xstart,xend]......
  • 力扣每日一题 6/19 排序+动态规划
    博客主页:誓则盟约系列专栏:IT竞赛专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞......