Count Triplets

Sort by

recency

|

811 Discussions

|

  • + 0 comments

    Recursive solution:

    def countTriplets(arr, r):
        sys.setrecursionlimit(10**6) #Avoid recursion error
        def rec_function(index, seconds, thirds, count):
            if index >= len(arr):
                return count
            i = arr[index]
            if i in thirds:
                count += thirds[i]
            if i in seconds:
                thirds[i * r] = thirds.get(i * r, 0) + seconds[i]
            seconds[i * r] = seconds.get(i * r, 0) + 1
            return rec_function(index + 1, seconds, thirds, count)
        
        return rec_function(0, {}, {}, 0)
    
  • + 0 comments
    def countTriplets(arr, r):
        seconds = {}
        thirds = {}
        count = 0
    
        for i in arr:
            
            if i in thirds:
                count += thirds[i]
    
            if i in seconds:
                if i * r in thirds:
                    thirds[i * r] += seconds[i]
                else:
                    thirds[i * r] = seconds[i]
    
            if i * r in seconds:
                seconds[i * r] += 1
            else:
                seconds[i * r] = 1
    
        return count
    
  • + 0 comments

    Simple Typescript solution with partitioning

    function countTriplets(arr, r) {
        const valuesAfterCurrent = new Map()
        arr.forEach((v) => {
            const count = valuesAfterCurrent.get(v) ? valuesAfterCurrent.get(v) + 1 : 1
            valuesAfterCurrent.set(v, count)
        }) //all here initially
        
        const valuesBeforeCurrent = new Map() //empty initially
        
        const res = arr.reduce((tripletsFound, currentValue) => {
            valuesAfterCurrent.set(currentValue, valuesAfterCurrent.get(currentValue) - 1)
            
            const frequencyOfFirstsOfTriple = valuesBeforeCurrent.get(currentValue / r) ?? 0
            const frequencyOfThirdsOfTriple = valuesAfterCurrent.get(currentValue * r) ?? 0
             
            const count = valuesBeforeCurrent.get(currentValue) ? valuesBeforeCurrent.get(currentValue) + 1 : 1
            valuesBeforeCurrent.set(currentValue, count)
            
            return tripletsFound + (frequencyOfFirstsOfTriple * frequencyOfThirdsOfTriple) //if any of the freq is zero it will not increase the current triplets found value
        }, 0) 
        
        return res
    }
    
  • + 0 comments

    can be solved in O(n)

    func countTriplets(arr []int64, r int64) int64 {
        pair := map[int64]int{}
        triple := map[int64]int{}
        count := 0
        for _, v := range arr{
            if c, ok := triple[v]; ok{
                count += c
            }
            if c, ok := pair[v]; ok{
                triple[v*r] += c
            }
            pair[v*r]++
        }
        return int64(count)
    }
    
  • + 0 comments

    Things to consider for this problem:

    • Overflows when multiplying the numbers
    • With the indices i < j < k, the numbers must be non-descending (e.g. 1, 4, 2 should not be considered a triplet). You can't just pick the three numbers from anywhere in the array.
    • The "corner case" with r = 1