Find Arrays In An Array

In a given array, find the number of sub-arrays that have the following properties:

  1. The first and the last number of sub-array is the same.
  2. A sub-array has more than one number in it.

Submit number of such sub-arrays as answer.

The array is described in file AinA.txt . First number ( 1 0 5 10^{5} ) is the number of elements in the given array. The rest of it are numbers that go in the array.

Answer is 5. With blue are marked all satisfactory sub-arrays Answer is 5. With blue are marked all satisfactory sub-arrays

Example with array of 8 elements.

Array: 3 1 7 5 5 7 3 7

Input Format and Details:

  • Link to input
  • The first line contains N N . The next line contains N N space seperated integers which constitute the array.
  • All integers, including the answer are less than 1 0 9 10^9

Questions can be asked here .


The answer is 648349.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

4 solutions

Christopher Boo
Aug 10, 2016

If a number occurs k > 1 k>1 times in the array, then we have ( k 2 ) k\choose 2 ways to pick that number as the first and last number of the sub-array. Hence, the answer is

x s e t ( A ) ( k x 2 ) \sum _{x\in set(A)} {k_x \choose 2}

In other words, for each unique number, we count its frequency and sum the number of ways to be selected as the first and last number of the sub-array.

Now, how do we implement this? A sneak peak into the test data gives us a sense that the numbers are huge (roughly 1 0 9 10^9 ). Hence we will use a map data structure to store the frequency of the numbers.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
using namespace std;

int N;
map<long long, long long> m;

int main() {

    scanf("%d",&N);
    for (int i = 0; i < N; i++) {
        long long x;
        scanf("%lld",&x);

        m[x]++; // keep track of frequency
    }

    long long ans = 0;
    // loop through all unique numbers
    for (map<long long, long long>::iterator it = m.begin(); it != m.end(); it++) {
        long long k = it->second;

        if (k < 2) continue;

        ans += k * (k - 1) / 2; // similar to k choose 2
    }

    cout << ans << endl;

    return 0;
}

This code returns 648349 648349 .

In python

1
2
3
4
5
6
7
8
9
def countaina(_array):
    r=0
    s=set(_array)
    for i in s:
        r+=(_array.count(i))*(_array.count(i)-1)/2
    return r
with open('AinA.txt','r') as file:
    exec('A=file.read().split( )')
print(countaina(A))

Rushikesh Jogdand - 4 years, 10 months ago
Lokesh Sharma
Aug 13, 2016
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Compute n choose 2
def nc2 n
    n * (n-1) / 2
end

# Read all the numbers
nums = File.read('AinA.txt').split.map(&:to_i)
# Forget the first number
nums.shift
# Create a hash mapping each number to the number of time it occurs
nums_hash = nums.inject(Hash.new(0)) { |total, e| total[e] += 1 ; total }
# Sums the nc2 of all values of the hash
nums_hash.values.map { |i| nc2 i }.inject :+

The algorithm is O(n) . It count the number of occurrences of each number in the file and uses that to compute the number of sub arrays possible.

Key Idea : If a number occurs x number of times, then the number of sub arrays starting and end at that number is n choose 2 .

Nice short code!

What does the expression { |total, e| total[e] += 1 ; total } mean?

Agnishom Chattopadhyay - 4 years, 10 months ago

Log in to reply

The expression { |total, e| total[e] += 1 ; total } executes two the statements total[e] += 1 and total in sequence.

You can read about Array#inject here . Its called by the name Fold in other functional programming languages I guess.

Lokesh Sharma - 4 years, 10 months ago
David Holcer
Nov 10, 2017
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
filee = open("/Users/davidholcer/Desktop/A/AinA.txt", "r") #opens file with name of "AinA.txt"
n=filee.readline()
nums=filee.readline().split(" ")
used=[]
total=0
c=0
while c < len(nums):
    if nums[c] not in used:
        x=nums.count(nums[c])
        total+=((x*(x-1))/2)
        used.append(nums[c])
    c+=1
print total

If number x appears n times, there are n(n-1)/2 ways to pick numbers one apart, two apart... all the way to n-1 apart, where numbers can be in between. Knowing this you just need to count the number of occurrences (x) of any given number, (making sure not to count a number twice) and use the formula f(x)=x(x-1)/2 to find the total arrays for x. Adding all values of all f(x) we obtain the total.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <iostream>
#include <fstream>
using namespace std;
main()
{
  long S = 0;
  fstream fin("old.txt", ios :: in);    // the contents of the array have been copied to this text file directly
  long a[100000];
  for(long i = 0; i < 100000; i++) fin >> a[i];
  fin.close();
  for(long i = 0; i < 99999; i++)
    for(int j = i+1; j < 100000; j++)
        if(a[j] == a[i])    S++;
  cout << S;
}

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...