• [LeetCode] 548. Split Array with Equal Sum


    Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions:

    1. 0 < i, i + 1 < j, j + 1 < k < n - 1
    2. Sum of subarrays (0, i - 1), (i + 1, j - 1), (j + 1, k - 1) and (k + 1, n - 1) should be equal.

    where we define that subarray (L, R) represents a slice of the original array starting from the element indexed L to the element indexed R.

    Example:

    Input: [1,2,1,2,1,2,1]
    Output: True
    Explanation:
    i = 1, j = 3, k = 5. 
    sum(0, i - 1) = sum(0, 0) = 1
    sum(i + 1, j - 1) = sum(2, 2) = 1
    sum(j + 1, k - 1) = sum(4, 4) = 1
    sum(k + 1, n - 1) = sum(6, 6) = 1

    Note:

    1. 1 <= n <= 2000.
    2. Elements in the given array will be in range [-1,000,000, 1,000,000].

    将数组分割成和相等的子数组。

    题意是给一个数组,请你找是否数组中存在这样一个三元组(i, j, k)满足i < j < k, (0, i - 1), (i + 1, j - 1), (j + 1, k - 1), (k + 1, n - 1)这四部分的数组和相等。注意这三个指针指向的值不包含在这四个区间里,也就是说比如你找到第一个指针i的时候,nums[i]是不会计算在(0, i - 1)或者(i + 1, j - 1)这两部分的子数组的和里面的。

    我这里给出的是前缀和 + hashset的思路。首先排除corner case是input数组长度小于7的情形。比如第一个例子,如果input数组长度小于7,你是无法满足条件找到这三个指针的位置的,所以长度小于7的数组是不行的。

    接着处理正常的case,创建一个数组记录原数组的前缀和,这样便于计算中间部分的数组和。

    接着自然是找每个指针的位置。但是你会发现如果先找第一个指针i的位置,虽然i的范围可以被确定下来,但是复杂度会很高,因为确定剩下两个指针的位置也是需要同样的复杂度,这一整套下来的复杂度起码是O(n^3)起跳。事实上这种做法也是无法通过OJ的。这里我提供一个优化的思路,我们可以先尝试确定第二个指针j的位置。一旦j的位置能确定下来,对于i指针来说,就是在0 - j之间two pointer夹逼找;同理对于k指针来说,就是在j - nums[nums.length - 1]之间two pointer夹逼找。其他部分可参见代码注释。

    时间O(n^2)

    空间O(n)

    Java实现

     1 class Solution {
     2     public boolean splitArray(int[] nums) {
     3         if (nums.length < 7) {
     4             return false;
     5         }
     6 
     7         int[] sum = new int[nums.length];
     8         sum[0] = nums[0];
     9         // create sum array: each sum has sum from 1 to i
    10         for (int i = 1; i < nums.length; i++)
    11             sum[i] = sum[i - 1] + nums[i];
    12 
    13         // for j - middle cut
    14         for (int j = 3; j < nums.length - 3; j++) {
    15             HashSet<Integer> set = new HashSet<>();
    16             // for i - left cut
    17             for (int i = 1; i < j - 1; i++) {
    18                 int sum1 = sum[i - 1];
    19                 int sum2 = sum[j - 1] - sum[i];
    20                 if (sum1 == sum2)
    21                     set.add(sum1); // add potential answers into set
    22             }
    23             // for k - right cut
    24             for (int k = j + 2; k < nums.length - 1; k++) {
    25                 int sum3 = sum[k - 1] - sum[j];
    26                 int sum4 = sum[nums.length - 1] - sum[k];
    27                 if (sum3 == sum4 && set.contains(sum3)) //
    28                     return true;
    29             }
    30 
    31         }
    32         return false;
    33     }
    34 }

    前缀和prefix sum题目总结

    LeetCode 题目总结

  • 相关阅读:
    1022 Digital Library (30 分)(map)
    1023 Have Fun with Numbers (20 分)(大整数运算)
    1019 General Palindromic Number (20 分)(回文数)
    Flink实时项目例程
    Spark Streaming+kafka+spring boot+elasticsearch实时项目(canal)
    Flink es-sink解决java.lang.NoSuchFieldError: FAIL_ON_SYMBOL_HASH_OVERFLOW
    Flink安装及WordCount实例yarn-cluster提交
    解决windows上The root scratch dir: /tmp/hive on HDFS should be writable.Current permissions are: ------
    RDD(弹性分布式数据集)介绍---Spark的核心
    Scala快速入门(零基础到入门)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13527007.html
Copyright © 2020-2023  润新知