lintcode 中等题:continuous subarray sum 联系子数组之和

题目

连续子数组求和

给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大。输出答案时,请分别返回第一个数字和最后一个数字的值。(如果两个相同的答案,请返回其中任意一个)

样例

给定 [-3, 1, 3, -3, 4], 返回[1,4].

解题

法一:直接暴力,时间复杂度O(N2),时间超时

public class Solution {
    /**
     * @param A an integer array
     * @return  A list of integers includes the index of the first number and the index of the last number
     */
    public ArrayList<Integer> continuousSubarraySum(int[] A) {
        // Write your code here
        ArrayList<Integer> result = new ArrayList<Integer>();
        int max = Integer.MIN_VALUE;
        for(int i = 0;i<A.length;i++){
            int sum = 0;
            for(int j = i;j<A.length; j++){
                sum += A[j];
                if(sum>max){
                    max = sum;
                    result.clear();
                    result.add(i);
                    result.add(j);
                }
            }
        }
        return result;
    }
}

Java Code

然后想到有过求最大子数组的和,只是返回最大子数组对于的和,本题是返回子数组的开始和结束的下标.

根据之前做题,突然想到,通过定义一个数组,来保存子数组的右边界是该元素时候的最大和,求出所有和的最大值就是最大子数组和的最大值.

public class Solution {
    /**
     * @param nums: A list of integers
     * @return: A integer indicate the sum of max subarray
     */
    public int maxSubArray(int[] nums) {
        // write your code
        int max = Integer.MIN_VALUE;
        int d[] = new int[nums.length];// 以i结束的元素的最大子数组之和
        d[0] = nums[0];
        max = d[0];
        for(int i=1 ;i<nums.length ; i++){
            d[i] = Math.max(d[i-1]+nums[i],nums[i]);
            max = Math.max(d[i],max);
            // System.out.println(d[i]);
        }
        return max;
    }
}

Java Code

可以看出,上面的数组其实可以换成两个变量的.之前看的网上的程序就是定义两个变量的.

本题是求的最大子数组的两个边界下标.

根据上面的思想,这个数组的下标是该子数组的右下标,而数组的值是子数组的左下标.。。。。然而发现实现不了。。。

网上就找到下面的程序,很好理解,但是自己写就会写乱。。。

public class Solution {
    /**
     * @param A an integer array
     * @return  A list of integers includes the index of the first number and the index of the last number
     */
    public ArrayList<Integer> continuousSubarraySum(int[] A) {
        // Write your code here
        ArrayList<Integer> result = new ArrayList<Integer>();
        int begin = 0;
        int end = 0;
        int sum = A[0];
        int maxsum = A[0];
        int maxbegin = 0;
        int maxend = 0;
        for(int i = 1;i<A.length;i++){
            if(sum <= 0){
                if(A[i] > sum){
                    begin = i;
                    end = i;
                    sum = A[i];
                }
                if(A[i] >= maxsum){
                    maxbegin = i;
                    maxend = i;
                    maxsum = A[i];
                }
            }else{
                sum +=A[i];
                if(sum> 0){
                    end = i;
                }
                if(sum > maxsum){
                    maxbegin = begin;
                    maxend = i;
                    maxsum = sum;
                }
            }
        }
        result.add(maxbegin);
        result.add(maxend);
        return result;
    }
}

Java Code

总耗时: 11178 ms

定义两对开始和结束的最大路径,一个用来保存当前路径的最大值得开始结束位置,一个用来保存所有路径的中最大值得开始结束位置。

当sum<0的时候 并且A[i] > sum 更新begin End sum

  当A[i] >=maxsum时候更新maxbegin maxend maxsum

当sum>0  sum+=A[i]

  此时若sum > 0 end 更新为当前的 i

  若 sum>maxsum 时候更新maxbegin maxend maxsum

最后结束的就是答案了

class Solution:
    # @param {int[]} A an integer array
    # @return {int[]}  A list of integers includes the index of the
    #                  first number and the index of the last number
    def continuousSubarraySum(self, A):
        # Write your code here

        begin,end,suma = 0,0,A[0]
        maxbegin,maxend,maxsum = 0,0,A[0]
        for i in range(1,len(A)):
            if suma < 0:
                if A[i] > suma :
                    begin = i
                    end = i;
                    suma = A[i]
                if A[i]>= maxsum:
                    maxbegin = i
                    maxend = i;
                    maxsum = A[i]
            else:
                suma +=A[i]
                if suma>0:
                    end = i
                if suma > maxsum:
                    maxbegin = begin
                    maxend = i
                    maxsum = suma
        return [maxbegin,maxend]

Python Code

总耗时: 673 ms

时间: 2024-12-24 13:49:54

lintcode 中等题:continuous subarray sum 联系子数组之和的相关文章

[LintCode] Continuous Subarray Sum 连续子数组之和

Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last number. (If their are duplicate answer, return anyone) Have you met this quest

[LeetCode] 209. Minimum Size Subarray Sum 最短子数组之和

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead. Example: Input: s = 7, nums = [2,3,1,2,4,3] Output: 2 Explanation: the subarr

lintcode 中等题: 3 Sum II 三数之和II

题目 三数之和 II 给一个包含n个整数的数组S, 找到和与给定整数target最接近的三元组,返回这三个数的和. 样例 例如S = [-1, 2, 1, -4] and target = 1.  和最接近1的三元组是 -1 + 2 + 1 = 2. 注意 只需要返回三元组之和,无需返回三元组本身 解题 和上一题差不多,程序也只是稍微修改了 public class Solution { /** * @param numbers: Give an array numbers of n integ

lintcode 中等题:4 Sum 四个数之和

题目 四数之和 给一个包含n个数的整数数组S,在S中找到所有使得和为给定整数target的四元组(a, b, c, d). 样例 例如,对于给定的整数数组S=[1, 0, -1, 0, -2, 2] 和 target=0. 满足要求的四元组集合为: (-1, 0, 0, 1) (-2, -1, 1, 2) (-2, 0, 0, 2) 注意 四元组(a, b, c, d)中,需要满足a <= b <= c <= d 答案中不可以包含重复的四元组. 解题 怎么感觉下面程序已经没法修改了但是在

lintcode 中等题:2 Sum 两个数的和

题目 两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是1到n,不是以0开头. 样例numbers=[2, 7, 11, 15], target=9 return [1, 2] 注意你可以假设只有一组答案. 解题 题目之前做LeetCode时候写过这个,利用这里利用ArrayList,当 target- numbers[i] 不在 list中,把numbers[i

Continuous Subarray Sum II(LintCode)

Continuous Subarray Sum II Given an circular integer array (the next element of the last element is the first element), find a continuous subarray in it, where the sum of numbers is the biggest. Your code should return the index of the first number a

LeetCode:Continuous Subarray Sum

523. Continuous Subarray Sum Add to List Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where

Continuous Subarray Sum II

Given an circular integer array (the next element of the last element is the first element), find a continuous subarray in it, where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last nu

《团队开发一(求一个数组的连续的子数组之和的最大值)》

(1)设计思想:一般的,求一个数组的最大子数组之和即是按数组顺序依次让前几个数的和与下一个数进行比较,设一变量来装每次比较后的较大的数,依此进行到数组终端:但是考虑到求的是连续的子数组,则应该想到除了在按顺序上的连续外,还得考虑到末端与首端的连续,所以按数组顺序依次求解得到的未必就是连续的最大的子数组之和,故此必须在此种情况下也求解出最大子数组之和,方法即是同时从数组的两端依次进行求出各自的最大子数组之和,然后在相遇前求和后与之前所求的最大子数组之和依次相比较,取它们中最大的一个作为连续的最大子