首页 > 试题广场 >

计算数组的小和

[编程题]计算数组的小和
  • 热度指数:1709 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
数组小和的定义如下:
(其中 的定义是第 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
# -*- coding: utf-8 -*-


#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param nums int整型一维数组
# @return long长整型
#
class Solution:
    """
    题目:
        https://www.nowcoder.com/practice/6dca0ebd48f94b4296fc11949e3a91b8?tpId=196&tqId=40415&rp=1&ru=/exam/oj&qru=/exam/oj&sourceUrl=%2Fexam%2Foj%3FjudgeStatus%3D2%26page%3D1%26pageSize%3D50%26search%3D%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196&difficulty=undefined&judgeStatus=2&tags=&title=
    借鉴:
        大神:???也能被占用,爷服了
    算法:
        本题与 NC188 数组中的逆序对 有些类似,属于同一类题目,都是基于归并排序的思想,在merge的时候,进行计算。
        核心思想是:
            在merge的时候,如果nums[l] <= nums[r],说明[r, right]区间内的所有元素都大于等于nums[l],nums[l]需要累加right - r + 1次
    复杂度:
        时间复杂度:O(nlogn)
        空间复杂度:O(n)
    """

    def calArray(self, nums):
        # write code here
        def mergeSort(left, right):
            if left >= right:
                return 0
            mid = left + ((right - left) >> 1)
            return mergeSort(left, mid) + mergeSort(mid + 1, right) + merge(left, mid, right)

        def merge(left, mid, right):
            L = right - left + 1
            tmpNums = [0] * L

            l, r, idx, ans = left, mid + 1, 0, 0
            while l <= mid and r <= right:
                if nums[l] <= nums[r]:
                    ans += (right - r + 1) * nums[l]
                    tmpNums[idx] = nums[l]
                    l += 1
                else:
                    tmpNums[idx] = nums[r]
                    r += 1
                idx += 1

            while l <= mid:
                tmpNums[idx] = nums[l]
                l += 1
                idx += 1

            while r <= right:
                tmpNums[idx] = nums[r]
                r += 1
                idx += 1

            for i in range(L):
                nums[left + i] = tmpNums[i]

            return ans

        n = len(nums)

        return mergeSort(0, n - 1)


if __name__ == "__main__":
    sol = Solution()

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

    # nums = [1]

    res = sol.calArray(nums)

    print res

发表于 2022-07-06 16:03:43 回复(0)

问题信息

难度:
1条回答 2143浏览

热门推荐

通过挑战的用户

查看代码