连续段数?

时间:2015-08-08 08:26:45

标签: algorithm math number-theory

N个整数和一个整数K的数组A.计算A的非空连续子序列的数量,使得该子段中没有坏的整数对。如果x位于数组中y的左侧并且x mod y = K,则一对(x,y)整数称为坏。

在小于或在θ(n ^ 2)中的任何更好的想法。 我尝试过的想法 -
一种解决方案是存储(在地图中)这样数量的对(在O(n ^ 2)中),然后迭代所有子段以进一步检查该段中存在与否的对并计算它....

子序列意味着: - 如果数组有N个元素而不是N *(N + 1)/ 2个子序列,即9,8,7,6,5那么我们有[9]; [8]; [7]; [6]; [5]; [9,8]; [8,7]; [7,6]; [6,5]; [9,8,7]; [8,7,6]; [7 ,6,5]; [9,8,7,6]; [8,7,6,5]; [9,8,7,6,5]都是子序列:) -

2 个答案:

答案 0 :(得分:0)

这是用Swift O(n)编写的解决方案。

基本思想是找到主序列中所有坏对的索引,然后用公式计算这些索引之间的子序列数(拆分坏对)。

势在必行的方法:

func numberOfSubsequences(array: [Int], k: Int) -> Int {
    // some spacial cases where you can return immediately
    if array.count <= 1 { return array.count }
    if array.count == 2 { return array[0] % array[1] == k ? 2 : 3 }

    var numberOfSubsequences = 0
    var startOfSubsequence = 0
    for i in 0..<array.count - 1 {
        // if a bad pair is found calculate the subsequence count between startOfSubsequence and i
        if array[i] % array[i+1] == k {
            let sequenceLength = i - startOfSubsequence + 1
            numberOfSubsequences += sequenceLength * (sequenceLength+1) / 2
            startOfSubsequence = i + 1
        }
    }
    // adding the remaining subsequence count from startOfSubsequence to the end of the array
    return numberOfSubsequences + (array.count - startOfSubsequence)*(array.count - startOfSubsequence + 1) / 2
}

使用尾递归的(更多)函数方法:

func numberOfSubsequences2(array: [Int], k: Int) -> Int {
    if array.count <= 1 { return array.count }
    if array.count == 2 { return array[0] % array[1] == k ? 2 : 3 }

    // find first index of a bad pair
    var i = 0
    while (i + 1 < array.count) && (array[i] % array[i+1] != k) {
        i++
    }
    let count = (i+1)*(i+2)/2

    // recurse over the remaining array (tail) from i+1 to the end
    let tail = Array(array[i+1..<array.count])
    return count + numberOfSubsequences2(tail, k: k)
}

答案 1 :(得分:-1)

  check this solution

  #include <iostream>
   using namespace std;

    int main() 
     {
     int n,k;
    cin>>n>>k;
     int a[n+1],i,j,ans=0;
     for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++){
    for(j=i+1;j<=n;j++){
        if(a[i]%a[j]==k){
            ans=ans+(n-j+1);
 break;
        }
    }
 }
    //if(k==0)ans=ans+n;
    cout<<n*(n+1)/2-ans;
// your code goes here
   return 0;
   }