C语言/数据结构贡献法题解:数组权值——所有连续子数组中不同数字个数之和(O(n)解法)

问题描述

小A最近在研究数组的权值问题。他发现一个数组的权值定义为:所有连续子数组中,不同数字的个数之和。例如,数组 1,2,1 的连续子数组有 1, 2, 1, 1,2, 2,1, 1,2,1,它们的权值分别是 1,1,1,2,2,2,总和为 1+1+1+2+2+2=9。

现在小A拿到了一个数组,他想请你帮忙计算这个数组的权值是多少。注意:数组可能包含重复元素,你需要高效地计算总权值。

要求:

  1. 设计一个算法,时间复杂度为 O(n),其中 n 是数组的长度。
  2. 尽量减少额外空间的使用,以体现你的算法优化能力。

测试样例

样例1:

输入:nums = [1,2,1] 输出:9 解释:所有连续子数组为 1 (权值1), 2 (权值1), 1 (权值1), 1,2 (权值2), 2,1 (权值2), 1,2,1 (权值2),总和为 1+1+1+2+2+2=9。

样例2:

输入:nums = [1,1,1] 输出:6 解释:连续子数组有 1 (权值1), 1 (权值1), 1 (权值1), 1,1 (权值1), 1,1 (权值1), 1,1,1 (权值1),总和为 1+1+1+1+1+1=6。

样例3:

输入:nums = [1,2,3] 输出:10 解释:连续子数组为 1 (1), 2 (1), 3 (1), 1,2 (2), 2,3 (2), 1,2,3 (3),总和为 1+1+1+2+2+3=10。

约束条件

  • 1 ≤ nums.length ≤ 1000
  • 1 ≤ numsi ≤ 1000
  • 数组长度 n 满足 1 ≤ n ≤ 1000

程序代码

#include <stdio.h>

#include <string.h>

int arrayWeight(int* nums, int numsSize) {

// lastPosvalue 记录每个值最近一次出现的位置

int lastPos1001;

for (int i = 0; i <= 1000; i++) {

lastPosi = -1;

}

int total = 0;

for (int i = 0; i < numsSize; i++) {

int val = numsi;

int prev = lastPosval;

// numsi 贡献的子数组数量

total += (i - prev) * (numsSize - i);

// 更新最近位置

lastPosval = i;

}

return total;

}

int main() {

int nums1\[\] = {1, 2, 1};

int nums2\[\] = {1, 1, 1};

int nums3\[\] = {1, 2, 3};

printf("%d\n", arrayWeight(nums1, 3)); // 9

printf("%d\n", arrayWeight(nums2, 3)); // 6

printf("%d\n", arrayWeight(nums3, 3)); // 10

return 0;

}

cpp 复制代码
#include <stdio.h>
#include <string.h>

int arrayWeight(int* nums, int numsSize) {
    // lastPos[value] 记录每个值最近一次出现的位置
    int lastPos[1001];
    for (int i = 0; i <= 1000; i++) {
        lastPos[i] = -1;
    }
    
    int total = 0;
    
    for (int i = 0; i < numsSize; i++) {
        int val = nums[i];
        int prev = lastPos[val];
        
        // nums[i] 贡献的子数组数量
        total += (i - prev) * (numsSize - i);
        
        // 更新最近位置
        lastPos[val] = i;
    }
    
    return total;
}

int main() {
    int nums1[] = {1, 2, 1};
    int nums2[] = {1, 1, 1};
    int nums3[] = {1, 2, 3};
    
    printf("%d\n", arrayWeight(nums1, 3));  // 9
    printf("%d\n", arrayWeight(nums2, 3));  // 6
    printf("%d\n", arrayWeight(nums3, 3));  // 10
    
    return 0;
}

运行结果

相关推荐
DongQiShanRen1 小时前
六根硬件映射(中):双站校验、生克闭环与驱动接口
数据库·人工智能·算法·rust·哈希算法·集成学习
mmmmath_31 小时前
LeetCode.637.二叉树的层平均值
算法·leetcode
Code_Solitude2 小时前
C语言分支结构练习题(华师版)
c语言·开发语言
青少儿编程课堂2 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会C/C++考级:并查集连通块与朋友圈问题解析
c++·python·算法·bfs·信息学竞赛
Tisfy2 小时前
LeetCode 2913.子数组不同元素数目的平方和 I:第一题先常数很大的O(n^2)
算法·leetcode·题解·模拟·暴力
H.莓飛2 小时前
【Linux】进程的创建与终止
linux·运维·服务器·c语言·visual studio
罗湖老棍子2 小时前
[USACO05NOV] Asteroids G(洛谷-P7368)
算法·图论·二分图匹配·最大匹配·最小顶点覆盖
从小白到软工2 小时前
4-1 指针
c语言·开发语言·数据结构·经验分享·ai编程
AI技术新视界2 小时前
Harness^2:递归自进化智能体Harnessing框架
人工智能·深度学习·算法·harness·rsi