列表

详情


NC349. 计算数组的小和

描述

数组小和的定义如下:
(其中 的定义是第 i 个数的左侧小于等于 的个数)

例如,数组 s = [1, 3, 5, 2, 4, 6] ,在 s[0] 的左边小于或等于 s[0] 的数的和为 0 ; 在 s[1] 的左边小于或等于 s[1] 的数的和为 1 ;在 s[2] 的左边小于或等于 s[2] 的数的和为 1+3=4 ;在 s[3] 的左边小于或等于 s[3] 的数的和为 1 ;
在 s[4] 的左边小于或等于 s[4] 的数的和为 1+3+2=6 ;在 s[5] 的左边小于或等于 s[5] 的数的和为 1+3+5+2+4=15 。所以 s 的小和为 0+1+4+1+6+15=27
给定一个数组 s ,实现函数返回 s 的小和

数据范围:

示例1

输入:

[1,3,5,2,4,6]

输出:

27

示例2

输入:

[1]

输出:

0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 18ms, 内存消耗: 2716KB, 提交时间: 2022-08-03

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @return long长整型
     */
    long long calArray(vector<int>& nums) {
        // write code here
        int a[202] = {0};
        long long z = 0;
         
        for (int& i : nums) {
            for (int j = i + 101; j > 0; j -= j & -j) {z += a[j];}           
            for (int j = i + 101; j < 201; j += j & -j) {a[j] += i;}
        }
        return z;
    }
    long long merge(vector<int>& nums, int l, int mid, int r) {
		int lb = mid - l + 1; // 左区间大小
		vector<int> help(lb);
		for (int i = 0; i < lb; i++) {
			help[i] = nums[i + l];
		}
		int p1 = 0, p2 = mid + 1;
		int p = l;
        long long res = 0;
		while (p1 < lb && p2 <= r) {
            res += help[p1] < nums[p2] ? (r-p2+1)*help[p1] : 0;
			nums[p++] = help[p1] < nums[p2] ? help[p1++] : nums[p2++];
		}
		while (p1 < lb) {
			nums[p++] = help[p1++];
		}
        return res;
        
	}
	long long mergeSort(vector<int>& nums, int l, int r) {
		if (l == r) {
			return 0;
		}
		int mid = l + ((r - l) >> 1);
        return mergeSort(nums, l, mid)+mergeSort(nums, mid + 1, r)+merge(nums, l, mid, r);
		
	}
};

C++ 解法, 执行用时: 19ms, 内存消耗: 2628KB, 提交时间: 2022-06-29

class Solution {
  public:
    long long calArray(vector<int>& nums) {
        int a[202] = {0};
        long long z = 0;
        
        for (int& i : nums) {
            for (int j = i + 101; j > 0; j -= j & -j) {z += a[j];}            
            for (int j = i + 101; j < 201; j += j & -j) {a[j] += i;}
        }
        return z;
    }
};

C++ 解法, 执行用时: 19ms, 内存消耗: 2712KB, 提交时间: 2022-05-21

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @return long长整型
     */
    long long calArray(vector<int>& nums) {
        int cnt[202] = {0};
        long long ans = 0;
        for (int & i : nums) {
            for (int j = i + 101; j > 0; j -= j & -j) {
                ans += cnt[j];
            }
            for (int j = i + 101; j < 201; j += j & -j) {
                cnt[j] += i;
            }
        }
        return ans;
    }
};

C++ 解法, 执行用时: 23ms, 内存消耗: 2724KB, 提交时间: 2022-06-26

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @return long长整型
     */
    long long calArray(vector<int>& nums) {
        long long preSum[201] = { 0 }, allMinSum;
        int vKey;
        for (int i = 0; i < nums.size(); i++) {
            vKey = nums[i] + 100;
            for (int j = vKey; j < 201; j++) {
                preSum[j] += 1;
            }
        }
        for (int i = 0; i < nums.size(); i++) {
            vKey = nums[i] + 100;
            for (int j = vKey; j < 201; j++) {
                preSum[j] -= 1;
            }
            if (vKey == 0) {
                allMinSum += (preSum[200] * nums[i]);
            } else {
                allMinSum += ((preSum[200] - preSum[vKey-1]) * nums[i]);
            }
        }

        return allMinSum;
    }
};

C 解法, 执行用时: 25ms, 内存消耗: 2224KB, 提交时间: 2022-07-06

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param nums int整型一维数组 
 * @param numsLen int nums数组长度
 * @return long长整型
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
long long calArray(int* nums, int numsLen ) {
    long long a[201] = { 0 }, z = 0;
    int f;
    for (int i = 0; i < numsLen; i++) {
        f = nums[i] + 100;
        for (int j = f; j < 201; j++) {
            a[j] += 1;
        }
    }
    for (int i = 0; i < numsLen; i++) {
        f = nums[i] + 100;
        for (int j = f; j < 201; j++) {
            a[j] -= 1;
        }
        if (f == 0) {
            z = z + (a[200] * nums[i]);
        } else {
            z = z + ((a[200] - a[f - 1]) * nums[i]);
        }
    }
    return z;
}

上一题