LeetCode Entry

947. Most Stones Removed with Same Row or Column

29.08.2024 medium 2024 kotlin rust

Count islands of intersecting x and y

947. Most Stones Removed with Same Row or Column medium blog post substack youtube 1.webp

Join me on Telegram

https://t.me/leetcode_daily_unstoppable/717

Problem TLDR

Count islands of intersecting x and y #medium #union-find

Intuition

The first intuition is to build a graph of connected dots and try to explore them.

2.png

After some meditation (or using a hint), one can see that all the connected dots are removed. Union-Find helps to find the connected islands.

Approach

  • we can connect each with each dot in O(n^2) (Rust solution)
  • or we can connect each row with each column and find how many unique rows and columns are in O(n) (Kotlin solution)

Complexity

  • Time complexity: \(O(n^2)\) or \(O(n)\)

  • Space complexity: \(O(n)\)

Code


    fun removeStones(stones: Array<IntArray>): Int {
        val uf = mutableMapOf<Int, Int>()
        fun f(a: Int): Int = uf[a]?.let { if (it == a) a else
            f(it).also { uf[a] = it }} ?: a
        for ((r, c) in stones) uf[f(r)] = f(-c - 1)
        return stones.size - uf.values.map { f(it) }.toSet().size
    }


    pub fn remove_stones(stones: Vec<Vec<i32>>) -> i32 {
        let (mut uf, mut res) = ((0..=stones.len()).collect::<Vec<_>>(), 0);
        fn f(a: usize, uf: &mut Vec<usize>) -> usize {
            while uf[a] != uf[uf[a]] { uf[a] = uf[uf[a]] }; uf[a] }
        for i in 0..stones.len() { for j in i + 1..stones.len() {
            if stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1] {
                let a = f(i, &mut uf); let b = f(j, &mut uf);
                if (a != b) { res += 1; uf[a] = b }
            }
        }}; res
    }