zoukankan      html  css  js  c++  java
  • [leetcode] Range Sum Query

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

    Example:

    Given nums = [-2, 0, 3, -5, 2, -1]
    
    sumRange(0, 2) -> 1
    sumRange(2, 5) -> -1
    sumRange(0, 5) -> -3
    

    Note:

    1. You may assume that the array does not change.
    2. There are many calls to sumRange function.

     分析:翻译一下,给定一个数组nums,要求找(i,j)位置中间的和,也就是nums[i]+...+nums[j]。最差的方法当然是一个一个求和,但是因为这个题目很巧妙,他在一个题目中设计了很多用例,也就是说很多计算结果会被重复用到,因此需要不能单纯的来一个用例就求和一次,要保存中间结果。很容易就想到用动态规划来做数组的求和,维护一个dp数组,其中dp[i]表示从0到第i位置的和,状态转移方程也很容易就得到了:dp[i] = dp[i-1]+nums[i],那么求(i,j)的和就是dp[j]-dp[i-1]就好了。代码如下:
     1 class NumArray {
     2     int[] dp;
     3     public NumArray(int[] nums) {
     4         if ( nums == null || nums.length == 0 ) return ;
     5         dp = new int[nums.length];
     6         dp[0]=nums[0];
     7         for ( int i = 1 ; i < nums.length ; i ++ ){
     8             dp[i] = dp[i-1]+nums[i];
     9         }
    10     }
    11 
    12     public int sumRange(int i, int j) {
    13         return i==0?dp[j]:dp[j]-dp[i-1];
    14     }
    15 }

          这里要注意第4行。运行时间125ms,击败96.34%。

          感觉还是有优化的空间的,因为这种方法考虑太多的特殊情况,能不能想办法将特殊情况也总结进去。看了一下solution,神奇的发现用一个长度为nums.length+1的数组就可以避免两种特殊情况的讨论了。代码如下:

     1 private int[] sum;
     2 
     3 public NumArray(int[] nums) {
     4     sum = new int[nums.length + 1];
     5     for (int i = 0; i < nums.length; i++) {
     6         sum[i + 1] = sum[i] + nums[i];
     7     }
     8 }
     9 
    10 public int sumRange(int i, int j) {
    11     return sum[j + 1] - sum[i];
    12 }

          设计很巧妙,可以学习。

  • 相关阅读:
    IP地址
    ACL访问控制列表
    DHCP原理及配置
    VRRP原理及配置
    ASP.NET CORE RAZOR :向 Razor 页面应用添加模型
    HBuilder + PHP开发环境配置
    添加相关功能
    基于stm32的水质监测系统项目基础部分详细记录
    表单数据验证方法(二)——ASP.NET后台验证
    表单数据验证方法(一)—— 使用validate.js实现表单数据验证
  • 原文地址:https://www.cnblogs.com/boris1221/p/9314215.html
Copyright © 2011-2022 走看看