skip to Main Content

I am trying to pair the duplicate elements of an array and count the pairs.

When given array is : [10, 20, 20, 10, 10, 30, 50, 10, 20], I’m expecting numberOfPairs to be 3. Because there are 2 pairs of 10s and 1 pair of 20.

My "if condition" is checking if current element’s index is first index or not. If it is not the last index, it means that there is a duplicate of the current element. So I’am adding 1 to numberOfPairs.

For input [10, 20, 20, 10, 10, 30, 50, 10, 20], my numberOfPairs is 2 but it should be 3.
For input [1 1 3 1 2 1 3 3 3 3], myNumberOfPairs is not printing at all? But instead it should be 4.

My What am I missing here?

func sockMerchant(n: Int, ar: [Int]) -> Int {
    // Write your code here
    var array = ar
    var numberOfPairs = 0
    
    for i in 0..<array.count {
       var element = array[i]
       let indexOfLastElement = array.lastIndex(of: element)
       let indexOfFirstElement = array.firstIndex(of: element)
       print("indexOfLastElement is (indexOfLastElement)")
       print("indexOfFirstElement is (indexOfFirstElement)")
       
       if indexOfFirstElement != indexOfLastElement {
           numberOfPairs += 1
           array.remove(at: indexOfFirstElement!)
           array.remove(at: indexOfLastElement!)
           continue
       }
       return numberOfPairs
    }
     return numberOfPairs
 }

3

Answers


  1. Chosen as BEST ANSWER

    So, I've solved the problem as below, thanks to @Vym and @Martin R.

    func sockMerchant(n: Int, ar: [Int]) -> Int {
    // Write your code here
    var array = ar
    var numberOfPairs = 0
    var newArray = [Int]()
    var done = false
    
    for i in 0..<array.count {
       let element = array[i]
       let indexOfLastElement = array.lastIndex(of: element)
       let indexOfFirstElement = array.firstIndex(of: element)
       
       if indexOfFirstElement != indexOfLastElement {
           newArray.append(element)
           numberOfPairs = newArray.count/2
           done = true
       }
       
    }
    if done == true {
        return numberOfPairs
    }
     return numberOfPairs
    

    }


  2. You’re mutating your array by calling remove(at:) at the same time as you’re accessing it which is why you’re having these weird side effects.

    I assume you’re trying to solve a Leetcode task (or something similar), so I won’t provide a solution upfront. My suggestion for you is to think of an algorithm that doesn’t involve changing the contents of the List while you’re reading these contents of that same List.

    Login or Signup to reply.
  3. I’m agree with @MartinR that in such cases you should place breakpoints and go throught your code line by line, glad you’ve found your mistake by yourself.

    But also in terms of performance, lastIndex and firstIndex are very heavy operations, because they may go thought all items and find nothing, which makes Big O notation of your algorithm around O(log n). In such cases dictionary is widely used(if you’re not much limited with the space).

    You can use value as a key and count as a value for a dictionary and count all items, then just sum like this:

    func sockMerchant(ar: [Int]) -> Int {
        ar.reduce(into: [Int:Int]()) { map, value in
            map[value, default: 0] += 1
        }.reduce(0) { sum, count in
            sum + count.value / 2
        }
     }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search