【问题标题】:Find sub sequence of array that have negative multiplication查找具有负乘法的数组子序列
【发布时间】:2020-03-07 05:23:24
【问题描述】:

我正在尝试构建一个算法,它可以为我提供元素的负积的子序列计数

例如:

[-1, 2, -3] 的答案是4。 ([-1][-3][-1, 2][2, -3]

【问题讨论】:

  • 可能是零吗?
  • 是的。零是可能的。

标签: arrays algorithm recursion subsequence


【解决方案1】:

一个让人头疼的方法是使用记忆。您可以定义一个记忆函数count_neg_seq_at(i),它返回从 indexi 开始的所有负子序列的计数。函数count_neq_seq_at(i) 可以根据count_neg_seq_at(i+1) 递归定义。最终答案由类似sum(count_neg_seq_at(i) for i = 1:n) 的东西给出,其中n 是数组的长度。

这是一个 Python 实现:

from functools import lru_cache
import numpy as np

np.random.seed(0)
arr = np.random.randint(-10, 10, 100)

# naive benchmark for checking correctness
from itertools import  combinations

def naive(xs):
  n = len(xs)
  count_neg = 0
  for i, j in combinations(range(n+1), 2):
    count_neg += sum(x < 0 for x in xs[i:j]) % 2
  return count_neg

# memoized approach
def count_negative_subseq(arr):
  neg = (arr < 0).astype(int)
  n = len(arr)
  # make a memoized function for counting negative subsequences
  # starting at a given index
  @lru_cache(None)
  def negative_starting_at(i):
    'number of subseqs with negative product starting at i'
    if i == n - 1:
      # base case: return one if the last element of the array is negative
      return neg[i]
    elif neg[i]:
      # if arr[i] is negative, return the count of positive product subsequences
      # from i+1 to n, plus one
      return n - i - negative_starting_at(i+1)
    else:
      # if arr[i] is positive, return count of negative product subsequences
      # from i+1 to n
      return negative_starting_at(i+1)

  # return sum of negative subsequences at each point
  return sum(negative_starting_at(i) for i in range(n))

print(naive(arr))
print(count_negative_subseq(arr))

# 2548
# 2548

【讨论】:

    【解决方案2】:

    线性算法(考虑零)。
    在第 i 步,res 增加了以第 i 个位置结尾的负积子序列的数量。

    def cntneg(a):
        negcnt = 0
        poscnt = 1
        mul = 1
        res = 0
        for i in range(len(a)):
            if a[i]== 0:
                negcnt = 0
                poscnt = 1
                mul = 1
            else:
                if a[i] < 0:
                    mul = - mul
                if mul > 0:
                    res += negcnt
                    poscnt += 1
                else:
                    res += poscnt
                    negcnt += 1
        return res
    
    print(cntneg([-1, 2, -3, 4, -5, 0, -1, 2, 2, -3]))
    >>15
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2020-08-30
      • 2016-01-08
      • 2017-01-12
      • 2021-04-25
      • 1970-01-01
      • 2017-03-21
      相关资源
      最近更新 更多