首页 > 其他分享 >LeetCode: 2552. 统计上升四元组 动态规划 时间复杂度O(n*n)

LeetCode: 2552. 统计上升四元组 动态规划 时间复杂度O(n*n)

时间:2024-09-10 16:51:41浏览次数:3  
标签:2552 nums int 复杂度 cnt 四元组 range cnt2

2552. 统计上升四元组

today 2552. 统计上升四元组

题目描述

给你一个长度为n下标从 0 开始的整数数组 nums ,它包含1n的所有数字,请你返回上升四元组的数目。

如果一个四元组 (i, j, k, l) 满足以下条件,我们称它是上升的:

  • 0 <= i < j < k < l < n
  • nums[i] < nums[k] < nums[j] < nums[l]

示例 1:

输入:nums = [1,3,2,4,5]
输出:2
解释:
- 当 i = 0 ,j = 1 ,k = 2 且 l = 3 时,有 nums[i] < nums[k] < nums[j] < nums[l] 。
- 当 i = 0 ,j = 1 ,k = 2 且 l = 4 时,有 nums[i] < nums[k] < nums[j] < nums[l] 。
没有其他的四元组,所以我们返回 2 。

示例 2:

输入:nums = [1,2,3,4]
输出:0
解释:没有四元组,所以我们返回 0 。

提示:

  • 4 <= nums.length <= 4000
  • 1 <= nums[i] <= nums.length
  • nums 中所有数字 互不相同 ,nums 是一个排列。

解题思路

我们可以枚举四元组中的 jk,那么问题转化为,对于当前的 j k

统计有多少个 l 满足 l>knums[l]>nums[j],记为cnt1
统计有多少个 i 满足 i<jnums[i]<nums[k],记为cnt2;

所以,对于每一组 jk,满足条件的组合数目为cnt1*cnt2,将所有jk组合数目相加,就是答案。

那么我们可以用动态规划解决这个问题。

使用二维数组 f 来记录 jk 组合的情况,f[j][k] 表示 有多少个l满足满足 l>knums[l]>nums[j]

初始化 f[j][n-1]0,表示对于末尾元素为k的情况下,没有满足条件的l。注意1<=j<n-2

从后往前填充行f[j],如果nums[k]>nums[j],则f[j][k-1]=f[j][k]+1

此时,对于每个jk,我们都可以计算出有多少个 l 满足 l>knums[l]>nums[j],即cnt1=f[j][k]

对于每个jk,我们已经通过二维数组 f,记录了cnt1的取值,接下来,我们只需要记录cnt2的取值即可。

对于每个jk,我们可以确定k,,之后从前往后遍历数组。
初始化cnt2=0,如果

  • nums[j]<nums[k],则cnt2+=1,表示当前有多少个i满足nums[i]<nums[k]
  • nums[j]>nums[k],则当前jk满足条件,我们将cnt2*cnt1cnt2*f[j][k]加入答案。

最后,返回答案即可。

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是数组的长度。
  • 空间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是数组的长度。

代码实现

Python实现:

class Solution(object):
    def countQuadruplets(self, nums):
        n=len(nums)
        f=[[0]*n for i in range(n)]
        ans=0
        for j in range(1,n-2):
            cnt=0
            for k in range(n-1,j,-1):
                f[j][k]=cnt
                if nums[k]>nums[j]:
                    cnt+=1
        for k in range(2,n-1):
            cnt=0
            for j in range(0,k):
                if(nums[j]>nums[k]):
                    ans+=cnt*f[j][k]
                else:
                    cnt+=1
        return ans

C++实现:

class Solution {
public:
    long long countQuadruplets(vector<int>& nums) {
        int n=nums.size();
        vector<vector<int>> f(n,vector<int>(n,0));
        long long res=0;
        for(int j=1;j<n-2;j++){
            int cnt=0;
            for(int k=n-1;k>j;k--){
                f[j][k]=cnt;
                if(nums[k]>nums[j]){
                    cnt++;
                }
            }
        }
        for(int k=2;k<n-1;k++){
            int cnt=0;
            for(int j=0;j<k;j++){
                if(nums[j]<nums[k]){
                    cnt++;
                    continue;
                }else{
                    res+=cnt*f[j][k];
                }
            }
        }
        return res;
    }
};

Go实现:

func countQuadruplets(nums []int) int64 {
	n := len(nums)
	f := make([][]int, n)
	for i := range f {
		f[i] = make([]int, n)
	}
	for j := 1; j < n-2; j++ {
		cnt := 0
		for k := n-1; k >j; k-- {
            f[j][k] = cnt
			if nums[j] < nums[k] {
				cnt++
			} 
		}
	}
	ans := 0
	for k := 2; k < n-1; k++ {
		cnt := 0
		for j := 0; j <k; j++ {
			if nums[j] < nums[k] {
				cnt++
                continue
			}else{
                ans+=cnt*f[j][k]
            }
		}
	}
	return int64(ans)
}

标签:2552,nums,int,复杂度,cnt,四元组,range,cnt2
From: https://blog.csdn.net/weixin_60214397/article/details/142103369

相关文章

  • 各排序算法及其时间复杂度比较
    排序算法及其时间复杂度比较在C语言中,排序算法是常见的算法之一,用于将一组数据按照一定顺序排列。下面我将简要介绍几种常见排序算法的时间复杂度,并给出每种排序算法的C语言代码示例。1.插入排序(InsertionSort)时间复杂度:平均和最坏情况:O(n^2)最好情况:O(n)(当输入数组已经排......
  • LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现N*K时间复杂度
    3177.求出最长好子序列II题目链接题目描述给你一个整数数组nums和一个非负整数k。如果一个整数序列seq满足在下标范围[0,seq.length-2]中最多只有k个下标i满足seq[i]!=seq[i+1],那么我们称这个整数序列为好序列。请你返回nums中好子序列的最长长度......
  • Unet改进23:添加DiverseBranchBlock||通过组合不同规模和复杂度的分支来增强单个卷积的
    本文内容:在不同位置添加DiverseBranchBlock目录论文简介1.步骤一2.步骤二3.步骤三4.步骤四论文简介我们提出了一种通用的卷积神经网络(ConvNet)构建块,在不需要任何推理时间成本的情况下提高其性能。该块被命名为多元分支块(DBB),通过组合不同规模和复杂度的分支来增强......
  • 浙大数据结构:01-复杂度2 Maximum Subsequence Sum
    数据结构MOOCPTA习题01-复杂度2MaximumSubsequenceSum#include<iostream>usingnamespacestd;constintM=100005;inta[M];intmain(){ intk; cin>>k; intf=1; for(inti=0;i<k;i++) { cin>>a[i]; if(a[i]>=0)//如......
  • 业务复杂度治理方法论--十年系统设计经验总结
    一、复杂度综述1、什么是复杂度软件设计的核心在于降低复杂性。--《软件设计的哲学》业界对于复杂度并没有统一的定义,斯坦福教授JohnOusterhout从认知负担和工作量方面给出了一个复杂度量公式子模块的复杂度cp乘以该模块对应的开发时间权重值tp,累加后得到系统的整体复杂度C这里的......
  • 业务复杂度治理方法论--十年系统设计经验总结
    一、复杂度综述1、什么是复杂度软件设计的核心在于降低复杂性。--《软件设计的哲学》业界对于复杂度并没有统一的定义,斯坦福教授JohnOusterhout从认知负担和工作量方面给出了一个复杂度量公式  子模块的复杂度cp乘以该模块对应的开发时间权重值tp,累加后得到系统的整......
  • 软件复杂度解决之道-续
    目录软件复杂性解决之道1.软件复杂性解决之道1.1. 简化需求:1.2.模块化:1.3.设计模式:1.4. 代码重构:1.5.定期重构代码以提高其可读性和可维护性,去除重复代码,优化结构。1.6. 自动化测试:1.7.持续集成/持续部署(CI/CD):1.8.代码审查:1.9.文档化:1.10.......
  • 【数据结构】时间复杂度空间复杂度
    1、时间复杂度1.1大O渐进表示法大O符号(BigOnotation):是用于描述函数渐进行为的数学符号。推导大O阶方法:用常数1取代运行时间中的所有加法常数。在修改后的运行次数函数中,只保留最高阶项。如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶......
  • Python深入理解快速排序算法及其时间复杂度分析
    Python深入理解快速排序算法及其时间复杂度分析快速排序(QuickSort)是一种高效的排序算法,广泛应用于各种实际场景中。它采用分治法(DivideandConquer)策略,通过选择一个基准元素(pivot),将数组分成两部分,使得左侧部分的元素都小于基准元素,右侧部分的元素都大于基准元素。然后递......
  • 信息学奥赛初赛天天练-81-NOIP2015普及组-完善程序-二分答案、二分查找、中位数、二分
    1完善程序(单选题,每小题3分,共30分)中位数median给定n(n为奇数且小于1000)个整数,整数的范围在0∼m(0<m<2^31)之间,请使用二分法求这n个整数的中位数。所谓中位数,是指将这n个数排序之后,排在正中间的数。(第五空2分,其余3分)01#include<iostream>02usingnamespace......