891. 子序列宽度之和https://leetcode.cn/problems/sum-of-subsequence-widths/

目录

题目描述:

解法思路:

优化思路:


题目描述:

一个序列的 宽度 定义为该序列中最大元素和最小元素的差值。

给你一个整数数组 nums ,返回 nums 的所有非空 子序列 的 宽度之和 。由于答案可能非常大,请返回对 109 + 7 取余 后的结果。

子序列 定义为从一个数组里删除一些(或者不删除)元素,但不改变剩下元素的顺序得到的数组。例如,[3,6,2,7] 就是数组 [0,3,1,6,2,2,7] 的一个子序列。

示例 1:

输入:nums = [2,1,3]
输出:6
解释:子序列为 [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3] 。
相应的宽度是 0, 0, 0, 1, 1, 2, 2 。
宽度之和是 6 。

示例 2:

输入:nums = [2]
输出:0

解法思路:

[2,1,3]的子序列为:[2], [1], [3], [2,1], [2,3], [1,3], [2,1,3]

宽度是:0 0 0 1 1 2 2 和为6

[1,2,3]的子序列为:[1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]

宽度是:0 0 0 1 2 1 2 和为6

由此不难发现子序列宽度之和与数组的元素顺序无关,因为题目中宽度的定义是最大值-最小值,而不是索引最大值-索引最小值。

所以我们先将数组排序。

由这个例子,我们不难推出:答案6=0(2-2)+0(1-1)+0(3-3)+1(2-1)+1(3-2)+2(3-1)+2(3-1) = (1*1 - 1*4) + (2*2 - 2*2) + (3*4 - 3*1)

由这个公式,我们可以得出一个结论:最后宽度之和 就是每个元素作为最大元素和(这个元素大小*当老大次数) - 作为最小元素和(这个元素大小*做老幺次数)

那么就可以推广这个公式到n:

1*2^0 - 1*2^(n-1) + 2*2^1 - 2*2^(n-2) +...+ (n-1)*2^(n-2) - (n-1)*2^1 + n*2^(n-1) - n*2^0

(其中1是第一个元素 n是第n个元素 2...(n-1)以此类推)

下面给出这道题的具体代码:

public class Main{public static void main(String[] args) {System.out.println(sumSubseqWidths(new int[]{2,1,3}));}private static int sumSubseqWidths(int[] nums) {final int MOD = 1000000007;Arrays.sort(nums);long sum = 0L;int n = nums.length;for (int i = 0; i < n; i++) {sum += (long) (nums[i] * Math.pow(2, i)) - (long) (nums[i] * Math.pow(2, n - 1 - i));}return (int) ((sum % MOD + MOD) % MOD);}
}

注意:公式中有减法,最后结果可能为负数,所以要先加上MOD,在对MOD取模

可惜的是,这个公式在运算数组长度较大的时候不能精确的算出结果,可能是因为

(long) (nums[i] * Math.pow(2, i)) - (long) (nums[i] * Math.pow(2, n - 1 - i)) 超过了long的范围

(Math.pow()需要的类型是double)

不过公式是正确的。

优化思路:

因为由上面的公式 可知 一个元素(第一个元素) 作为最大元素次数 与 其对称元素(最后一个元素)作为最小元素次数 相等

公式:1*2^0 - 1*2^(n-1) + 2*2^1 - 2*2^(n-2) +...+ (n-1)*2^(n-2) - (n-1)*2^1 + n*2^(n-1) - n*2^0

如上面标注出的 1的最大次数 等于 n的最小次数

那么这个公式就可以改写成:

(1-n)*2^0 + (2-(n-1))*2^1 +...+ ((n-1)-2)*2^(n-2) + (n-1)*2^(n-1)

于是就可以给出优化后的代码:

public class Main{public static void main(String[] args) {System.out.println(sumSubseqWidths(new int[]{2,1,3}));}private static int sumSubseqWidths(int[] nums) {final int MOD = 1000000007;Arrays.sort(nums);long sum = 0L;int n = nums.length;long pow = 1L;//2^0=1for (int i = 0; i < n; i++) {sum += (nums[i] - nums[n - 1 - i]) * pow;pow = pow * 2 % MOD;}return (int) ((sum % MOD + MOD) % MOD);}
}

每次求和 和 相乘的次数(2的几次方)都对MOD取模了,所以不用担心会超过数据范围

要注意的是 子序列为单个元素时 两种计算公式都额外当成了 作为最大元素与最小元素各一次 但都减去了 所以对结果无影响

力扣每日一题:891. 子序列宽度之和(java)相关推荐

  1. 【JAVA】交错字符串——力扣每日一题(六)(2020.07.18)

    目录 题目:97. 交错字符串 思路 如果你从本文中学习到丝毫知识,那么请您点点关注.点赞.评论和收藏 大家好,我是爱做梦的鱼,我是东北大学大数据实验班大三的小菜鸡,非常渴望优秀,羡慕优秀的人,个人博 ...

  2. leetcode 力扣每日一题系列详解——总目录

    这是总目录,该系列持续更新中........ leetcode 力扣每日一题系列详解--总目录

  3. 【爬虫】力扣每日一题每天自动邮件提醒!!!

    使用python实现了一个力扣每日一题每天自动邮件提醒的小爬虫,小但实用!!! 文章目录 A.需求来源与分析 B.技术角度分析 C.具体分析步骤 1.接口协议分析 2.发邮件 3.写crontab放服 ...

  4. 力扣每日一题每天自动邮件提醒

    A.需求来源与分析 需求来源于生活,对于只是偶尔有兴趣做做题的我,力扣的每日一题对我一直有以下的不便: 太简单不想做,需要花太多时间的不想做,每天打开力扣其实只是想看一下是什么题,有意思才做. 看题需 ...

  5. 力扣每日一题:1720.解码异或后的数组 python异或操作

    1720.解码异或后的数组 https://leetcode-cn.com/problems/decode-xored-array/ 难度:简单 题目: 未知 整数数组 arr 由 n 个非负整数组成 ...

  6. LeetCode 力扣每日一题 488.祖玛游戏

    题目描述: 你正在参与祖玛游戏的一个变种. 在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 'R'.黄色 'Y'.蓝色 'B'.绿色 'G' 或白色 'W' .你的手中也有一些彩 ...

  7. 力扣每日一题——两数相加II

    发现做的题难度始终不高,今天Leecode给了一个稍微难一点的题目.(前两天没更是因为去拔牙了~~>_<~~) 给你两个 非空 链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每 ...

  8. 2022.1.4 力扣-每日一题-猫和老鼠

    题目描述: 两位玩家分别扮演猫和老鼠,在一张 无向 图上进行游戏,两人轮流行动. 图的形式是:graph[a] 是一个列表,由满足 ab 是图中的一条边的所有节点 b 组成. 老鼠从节点 1 开始,第 ...

  9. 力扣每日一题——独一无二出现的次数

    难度:简单 题目: 给你一个整数数组 arr,请你帮忙统计数组中每个数的出现次数. 如果每个数的出现次数都是独一无二的,就返回 true:否则返回 false. 示例 1: 输入:arr = [1,2 ...

最新文章

  1. ios searchBar 的代理方法 集合
  2. C++基本要点复习--------coursera程序设计实习(PKU)的lecture notes
  3. of type std::bad_cast: std::bad_cast
  4. Pandas实战教程 | DataFrame连接 pd.concat()
  5. Java基础之static关键字的用法
  6. 如何解决Document transaction is being distributed的message
  7. .net 实时通信_基于 RabbitMQ 的实时消息推送
  8. 西安工业学院计算机系王翊,西安文理学院艺术学院
  9. Qt工作笔记-视图/模型以及过滤代理模型的使用
  10. java获取窗口_如何使用Java获取当前打开的窗口/进程的列表?
  11. 云开发初探 —— 更简便的小程序开发模式
  12. C#相关控件使用总结
  13. 杭电多校第三次 Problem A. Ascending Rating(单调队列)
  14. 《WinHex》误使用Ghost恢复系统恢复数据图文教程
  15. 易语言 互联网浏览器支持库 WEB浏览器2.0版(WebBrowser2.fne)
  16. cfree 上面工具栏消失解决办法(不用重下!!!!!)
  17. python爬取网易云音乐评论并进行情感分析_使用python3爬取网易云音乐的评论
  18. SkeyeVSS实现RTSP、Onvif监控摄像头网页无插件化直播监控解决方案
  19. alertdialog旋转屏幕消失造成leak window
  20. hdu 4394 Digital Square【标准DFS】

热门文章

  1. 使用Wifi pineapple(菠萝派)进行Wi-Fi钓鱼攻击
  2. 蔡学镛[散文随笔]:从A到E+
  3. 自己动手做一个PLC 软PLC
  4. 【hadoop生态之ZooKeeper】第三章ZooKeeper内部管理【笔记+代码】
  5. 【QT】The inferior stopped because it received a signal from the operating system及opencv_gapi模块cmake错误
  6. icloud显示账户详情不可用,苹果icloud账户详情不可用怎么办 iPhone提示当前账户详情不可用怎么回事...
  7. 可视化设计,类Excel的快速开发平台
  8. 应用程序如何隐藏标题栏
  9. 计算机中的网络怎么共享的打印机驱动,如何共享打印机,如何设置打印机共享打印机共享设置图解-中关村在线...
  10. nyoj 543 遥控器 第五届河南省程序设计大赛