|
给定一个非负整数组和一个数字。您需要打印总和等于给定整数子数组的所有开始和结束索引。- C) w, d/ _' a8 x
例如 :2 [9 O- T8 D: g5 f6 e
Input-int[] arr = {int num = 9Output-starting index : 1,Ending index : 2starting index : 5,Ending index : 5starting index : 5,Ending index : 6Explanation :) a9 M" ^ F/ y& \' {; R6 c9 a e
[3,6] [9],
7 R9 F( R M: x- s7 [[9,0] These all are the subarrays with their sum equal to 9.
3 S: ~! Q9 x2 L% w 8 @3 l: B& ^) E6 z. `
解决方案:
: _0 P! T: V* o* P4 z8 R 解决这个问题的基本蛮力方法是生成给定数组的所有子数组,然后遍历生成的子数组并计算总和。如果总和等于给定总和,则打印子数组,因为它是我们解决方案的一部分。
* q( C+ k7 P; h4 ^现在我们知道一个有 n 个元素数组有n*(n 1)/2 个子数组。
* T* K- H& Z7 f0 G+ J' n! S3 k如何?
$ v, Q7 F+ U! s考虑一个数组,( W, }5 o G3 X. U; p) K: Q" j3 K
int[] arr = {a1,a2,a3,a4…,an};Subarrays starting with 0th index,a1a1,a2a1,a2,a3a1,a2,a3,a4...a1,a2,a3,a4…,anSubarrays starting with 1st index,a2a2,a3a2,a3,a4...a2,a3,a4…,ansubarrays starting with 2nd index,a3a3,a4...a3,a4…,anSubarrays starting with last i.e. 3rd index,a4...a4…,an现在,
! T$ l" `# ^( v h总子数组= 从第 0 个 idx子数组 从第 1 个 开始idx 开始子数组 . p3 l3 u# Z1 ?: a* S7 i0 R
第二 个 idx 子数组开始。. . 以第 n 个 idx 开头的子数组6 o' |2 T% ]7 M' z: r
Sn = n (n-1) (n-2) (n-3) ... 1
, _ f1 C! C9 N* j& d3 mSn = n(n 1)/2
- V( j* M8 j6 f# ~7 K在那里,生成所有子数组并计算答案将花费我们最坏的时间复杂性,O(n(n 1)/2)其顺序为O(n^2)。
% W9 G9 ^- l$ N8 Wpackage Arrays;import java.util.Scanner;public class targetsumSubarr public static void main(String[] args) Scanner scn = new Scanner(System.in); int[] arr = new int[scn.nextInt();int target = scn.nextInt();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;for (int i = 0; i 有效方法:( R/ A6 ]( c# {* b& v% ^
我们可以在线性时间内解决这个问题,即O(n)时间复杂度最差。) [) p) i: O; L% B$ \
我们可以维护两个指针,一个基本上代表一个子数组的指针,start并且end我们必须拿一个变量来存储current sum子数组从指针开始到指针结束。
- P5 H" `8 R6 p0 E我们end指针在添加元素的同时不断增加,current sum直到我们达到当前运行总和大于所需目标总和的点,这基本上意味着我们计算的总和不是当前子数组的正确答案。1 R9 H5 f0 N. E6 {8 k. `' S
所以现在我们通过移动移动start指针改变我们的子数组,即缩短子数组,从而缩短当前总和,希望实现当前总和等于所需目标总和。
4 X7 m: a. f; Y/ D: v- l0 }在每一点上,我们检查我们目前的总和是否等于目标总和。如果是这样,我们会打印我们的指针。
3 U+ @0 y4 |, D& @% {; o因此,基本上,我们通过增加改变子数组start和end与其价值相比,目标总电流总和取决于指针和变化。
/ w: e9 Y- _; ? J% c1 O2 _package org.arpit.java2blog;import java.util.Scanner;public class TargetsumSubarr public static void main(String[] args) Scanner scn = new Scanner(System.in); int[] arr = new int[scn.nextInt();int target = scn.nextInt();;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;for (int i = 0; i target) { currSum -= arr[start]; start else { /* we add the last element to our * currSum until our * sum becomes greater than or * equal to target sum. * we keep on subtracting the start element * until it is less than or equal to required target sum. */ if (currSum > target) { currSum -= arr[start]; start ; } else { /* we add the last element to our * currSum until our * sum becomes greater than or * equal to target sum. * if (end 当您操作上述程序时,您将获得以下输出:* F$ g: I9 O& A) D! O- m
792 3 6 9 arr[]starting index : 1,Ending index : 2starting index : 4,Ending index : 4starting index : 4,Ending index :5 |
|