• 413.等差数列划分


    413.等差数列划分

    题目:

    如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。

    例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。
    给你一个整数数组 nums ,返回数组 nums 中所有为等差数组的 子数组 个数。

    子数组 是数组中的一个连续序列。

    示例 1:

    输入:nums = [1,2,3,4]
    输出:3
    解释:nums 中有三个子等差数组:[1, 2, 3]、[2, 3, 4] 和 [1,2,3,4] 自身。
    示例 2:

    输入:nums = [1]
    输出:0

    解法一 动态规划

    动态规划重要几点:(1) dp[i]的定义;(2)状态;(3)选择;

    dp[i]的定义:表示第i个元素包括第i个元素之前的所有等差数列。

    状态:选择了这个元素,可以组成更长的等差数组。或者选择了这个元素,不能组成更长的等差数组。

    选择:只能选择下一个。

    所以动态规划的方程为:

    dp[i] = dp[i-1]+1 //如果能组成更长的等差数组
    dp[i] = 0 //如果组不成更长的等差数组
    

    如果能组成更长的等差数组:那么num[i]-num[i-1] == num[i-1]-num[i-2]

    否则的话不能组成。所以动态规划方程就出来了。

    需要注意的是,一般情况下,在开始动态规划的时候,需要定义初始状态,这道题中初始状态都是0,所以可以直接去掉。具体看代码提示。

    image-20210810154932459

    代码

    class Solution {
        public int numberOfArithmeticSlices(int[] nums) {
            int n = nums.length;
            int[] dp = new int[n];
            //这里应该有初始状态.即dp[0]=dp[1]=dp[2] = 0,可以不用罗列,具体原因:
            //在定义数组的时候,基本类型的数组初始化为零值.int的话为0,boolean的话是false。
            for (int i = 2; i < n; i++) {
                if (nums[i]-nums[i-1] == nums[i-1]-nums[i-2]){
                    dp[i] = dp[i-1]+1;
                }else {
                    dp[i] = 0;
                }
            }
            return Arrays.stream(dp).sum();
        }
    }
    

    解法二:查分+计数

    leetcode的官方题解。

    感觉讲的太复杂了,代码其实挺简单的。

    image-20210810161211163

    public int numberOfArithmeticSlices(int[] nums) {
            int n = nums.length;
            if (n == 1) {
                return 0;
            }
    
            int d = nums[0] - nums[1], t = 0;
            int ans = 0;
            //因为等差数列的长度至少为3,所以可以从i=2开始枚举
            for (int i = 2; i < n; i++) {
                if (nums[i-1] - nums[i] == d){
                    ++t;
                }else{
                    d = nums[i-1] - nums[i];
                    t= 0;
                }
                ans+=t;
            }
            return ans;
        }
    

    就是在循环数组中的每个数,多设置一个重置位,当不满足等差定义的时候,将重置位置为0,否则的话重置位++,每次循环把重置位和ans相加即可。

    博客网站 https://yamon.top 个人网站 https://yamon.top/resume GitHub网站 https://github.com/yamonc 欢迎前来访问
  • 相关阅读:
    B/S---控件属性
    Windows Form -----内容(11)
    C#--Web控件简介
    C#控件基本1
    C#增删改小总结
    C#播放器控件的常用方法介绍
    C#封装---小练
    链接SQL、事务---小总结
    事务-----2
    事务----1
  • 原文地址:https://www.cnblogs.com/chenyameng/p/15124442.html
Copyright © 2020-2023  润新知