Description

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 number.

If duplicate answers exist, return any of them.

Example

Example 1:

Input: [3, 1, -100, -3, 4]
Output: [4, 1]

Example 2:

Input: [1,-1]
Output: [0, 0]

Challenge

O(n) time

思路:

分两种情况讨论:

  1. 最大数组仍然是中间的某一段
  2. 最大数组是去掉了中间的一段之后剩下的部分

第一种情况用传统的最大子数组做法走一遍(参考题解)。第二种做法稍微想一下就可以证明中间被去掉的那一段是整个数组的 minimum subarray。
所以求一遍 minimum subarray 之后,比较两种情况, 取最优解即可

需要特殊考虑 minimum subarray 是取了所有数的情况。

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
*/ class Result{
public int maxSum;
public int leftIdx, rightIdx;
} // coef = 1: find the maximum non-empty subarray
// coef = -1: find the maximum non-empty subarray
// A[i] *= coef
Result findMax(int[] A, int coef) {
// Sj // S{i-1} // i-1
int j, nowSum = 0, prevMinSum = 0, prevMinIdx = -1;
Result res = new Result();
res.maxSum = Integer.MIN_VALUE;
for (j = 0; j < A.length; ++j) {
nowSum += A[j] * coef;
// Sj- prevMinSum
if (nowSum - prevMinSum > res.maxSum) {
res.maxSum = nowSum - prevMinSum;
res.leftIdx = prevMinIdx; // i - 1
res.rightIdx = j;
} if (nowSum < prevMinSum) {
prevMinSum = nowSum;
prevMinIdx = j;
}
} return res;
} public List<Integer> continuousSubarraySumII(int[] A) {
Result max = findMax(A, 1);
Result min = findMax(A, -1);
min.maxSum *= -1; int totSum = 0;
for (int i = 0; i < A.length; ++i) {
totSum += A[i];
} List<Integer> res = new ArrayList<>();
if (max.maxSum >= totSum - min.maxSum) {
res.add(max.leftIdx + 1);
res.add(max.rightIdx);
}
else {
// special case
if (min.leftIdx == -1 && min.rightIdx == A.length - 1) {
res.add(max.leftIdx + 1);
res.add(max.rightIdx);
}
else {
// use complementary interval for min interval
// [min.leftIdx+1...min.rightIdx]
// min.rightIdx + 1 ... len-1, 0, 1, ... min.leftIdx
res.add(min.rightIdx + 1);
res.add(min.leftIdx);
}
} return res;
}
}

  

Continuous Subarray Sum II的更多相关文章

  1. Continuous Subarray Sum II(LintCode)

    Continuous Subarray Sum II   Given an circular integer array (the next element of the last element i ...

  2. [LintCode] Continuous Subarray Sum II

    Given an integer array, find a continuous rotate subarray where the sum of numbers is the biggest. Y ...

  3. [LintCode] Subarray Sum & Subarray Sum II

    Subarray Sum Given an integer array, find a subarray where the sum of numbers is zero. Your code sho ...

  4. LintCode 402: Continuous Subarray Sum

    LintCode 402: Continuous Subarray Sum 题目描述 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的下标 ...

  5. leetcode 560. Subarray Sum Equals K 、523. Continuous Subarray Sum、 325.Maximum Size Subarray Sum Equals k(lintcode 911)

    整体上3个题都是求subarray,都是同一个思想,通过累加,然后判断和目标k值之间的关系,然后查看之前子数组的累加和. map的存储:560题是存储的当前的累加和与个数 561题是存储的当前累加和的 ...

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

    Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...

  7. Continuous Subarray Sum

    Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...

  8. [LeetCode] Continuous Subarray Sum 连续的子数组之和

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

  9. [Swift]LeetCode523. 连续的子数组和 | Continuous Subarray Sum

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

随机推荐

  1. CI 框架 伪静态设置 去掉index.php

    .htaccess文件修改 DirectoryIndex index.php RewriteEngine on RewriteBase / RewriteCond %{REQUEST_FILENAME ...

  2. PAT(B) 1050 螺旋矩阵(Java:24分)

    题目链接:1050 螺旋矩阵 (25 point(s)) 题目描述 本题要求将给定的 N 个正整数按非递增的顺序,填入"螺旋矩阵".所谓"螺旋矩阵",是指从左上 ...

  3. 函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!闭包访问局部变量

    函数内部声明变量的时候,一定要使用var命令.如果不用的话,你实际上声明了一个全局变量! function f1(){ n=999; } f1(); alert(n); 子函数可以一层一层读取到父元素 ...

  4. Logrotate滚动openresty日志

    一.摘要 Linux服务器上我们用Logrotate来分割归档日志文件,结合crond我们可以指定每天在某个时间自动整理日志等文档.本文主要说明了Centos下Logrotate的使用和配置的方法. ...

  5. Python Paramiko实现sftp文件上传下载以及远程执行命令

    一.简介 Paramiko模块是基于Python实现的SSH远程安全连接,用于SSH远程执行命令.文件传输等功能. 安装模块 默认Python没有自带,需要手动安装: pip3 install par ...

  6. WebAPI 之问题记录

    这篇博客是博主的第一篇博客,主要用于webapi学习过程中的问题记录 问题1:  重写OnAuthorization权限验证时,遇到AllowAnonymousAttribute特性不起作用的问题 p ...

  7. 私有属性和私有方法l

    class Woman: def __init__(self, name): self.name=name self.__age=18 def __secret(self): print(" ...

  8. docker 容器和镜像常用命令整理

  9. Markdown 初学总结

    Markdown Tutorial(Typora-Specific) 1. Headers 最多可有六级标题,在标题前加 # 作为标记.注意标记与标题内容之间有空格: # 这是一级标题 ## 这是二级 ...

  10. Http 请求头包含哪些信息?

    协议头 说明 示例 状态 Accept 可接受的响应内容类型(Content-Types). Accept: text/plain 固定 Accept-Charset 可接受的字符集 Accept-C ...