LeetCode 记录 (2281) 巫师总力量总和

  1. 题目描述:
    在这里插入图片描述

  2. 题目化简:
    对数组的所有子数组分别进行一定操作(求最小值*元素和)后求和。

  3. 思路
    (1)找到最小值,将数组分为 包含该值的所有子数组和不包含该值的所有子数组。
    (2)不包含该值的所有子数组,可以分为左右两个单独数组,进行递归操作。
    (3)问题到此化简为,对数组所有子数组内的元素求和,再求和。
    问题聚焦为:每个元素被加了多少遍,及即包含min和该元素的子数组共有多少个。
    找规律发现,该值为(左侧元素个数+1)*(右侧元素个数+1),代码如下:

for(int j = 0 ; j<n ; j++){
            long temp = (long)(Math.min(j,point)+1) * (n-Math.max(j,point)) ; 
            temp2 =temp2 + strength[j] * temp;
        }
  1. 执行测试用例发现的问题
    (1)程序中乘法或者加法超过Int范围问题
    先将Int转换成long后再操作,最后对long进行取余。
    (2)递归造成的内存不足问题
    用循环替代递归

  2. 代码

class Solution {
    public int totalStrength(int[] strength) {
        int n = strength.length;
        if(n == 1){
            long temp4 = (long)strength[0] * strength[0];  // int 转换成 long 再 乘
            temp4 = temp4 % ((long)(Math.pow(10.0,9.0)) + 7) ;
             return (int)temp4;
        }
        int left = 0 ;
        int right = 0;
        long mid = 0;
        int min = Integer.MAX_VALUE;
        int point = 0;
        int secfen = n/2;
        int flag =Integer.MAX_VALUE;
        for(int i=0 ; i<n;i++){
            if(strength[i]<min) {
                min = strength[i];
                point = i ;
            }
            else if(strength[i]==min){
                int dis = Math.abs(point - secfen);
                if(dis<flag){
                    point = i ;
                    flag = dis;
                }
            }
        }
        if(point != 0 ) left = totalStrength(Arrays.copyOfRange​(strength,0,point));
        if(point != n-1) right= totalStrength(Arrays.copyOfRange​(strength,point+1,n));
        long temp2 =0;
        for(int j = 0 ; j<n ; j++){
            long temp = (long)(Math.min(j,point)+1) * (n-Math.max(j,point)) ; // int 转换成 long 再 乘

            temp2 =temp2 + strength[j] * temp;
            temp2 = temp2 % ((int)(Math.pow(10.0,9.0)) + 7) ;
        }
        mid = (long)min * temp2;
        long temp3 = mid + left + right;
        temp3 = temp3 % ((int)(Math.pow(10.0,9.0)) + 7) ; // 去掉了 判断
        int all = (int)temp3;
        return all;

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值