LeetCode Entry

1488. Avoid Flood in The City

07.10.2025 medium 2025 kotlin rust

Replace zeros with numbers to avoid duplicates search

1488. Avoid Flood in The City medium blog post substack youtube

1 (5).webp

Join me on Telegram

https://t.me/leetcode_daily_unstoppable/1135

Problem TLDR

Replace zeros with numbers to avoid duplicates #medium #binary_search #greedy

Intuition

    // 0 1 2 3 4 5 6 7 8 9 1011
    // 1 2 0 0 3 4 0 0 3 4 1 2
    //                 i       - first filled, use zero at index 2

    // 0 1 1 - corner case
    //     i -- can't use zero, because no zero before previous 1

    // 0 0 0 0 0 0 2 1 2

    // 0 0 0 0 0 0 2 0 0 1 2 1
    //       ^
    //       can i use any of these? - no

    // 1 2 0 0 3 4 0 0 3 4 1 2
    //             * * i
    //     * *     * *     i      i can use zeros between duplicates
    //                            or, zero can be used for any element before it
    //
    //                            which one to choose? closest

    // 1 2 0 0 2 1
    // 1 2 0 2 0 1
    // 1 0 2 0 2 1

    // 1 2 0 1 0 2
    // 1 0 2 0 1 2

    // 0 1 1
    // i       zi  = [0]
    //   i     fi[1] = 1

    // 0 1 2 3 4 5 6
    // 1 0 2 3 0 1 2
    // i         .     fi[1] = 0
    //   i       .     zi = [1]
    //     i     .     fi[2]=2
    //       i   .     fi[3]=3
    //         i .     zi=[1,4]
    //           i     prev=fi[1]=0, 4>1, res[4]=1, ok so this breaks 2
    //                                              closest is not optimal
    //                                    "smallest after"

  • remember zero days
  • when seeing a duplicate, pick the first zero after the previous duplicate instance

Approach

  • use the BinarySearch or TreeSet .higher(x)

Complexity

  • Time complexity: \(O(nlog(n))\)

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

Code


// 64ms

    fun avoidFlood(r: IntArray): IntArray {
        val zi = TreeSet<Int>(); val fi = HashMap<Int, Int>()
        for ((i, l) in r.withIndex()) if (l > 0) {
            if (fi[l] != null) r[zi.higher(fi[l]) ?: return intArrayOf()] = l
                .also { zi -= zi.higher(fi[l]) }
            fi[l] = i; r[i] = -1
        } else { zi += i; r[i] = 1 }
        return r
    }


// 21ms

    pub fn avoid_flood(mut r: Vec<i32>) -> Vec<i32> {
        let (mut f, mut z) = (HashMap::new(), BTreeSet::new());
        for i in 0..r.len() { let l = r[i];
            if l == 0 { z.insert(i); r[i] = 1; continue }
            if let Some(&j) = f.get(&l) {
                let Some(&d) = z.range(j+1..).next() else { return vec![] };
                r[d] = l; z.remove(&d); }
            f.insert(l, i); r[i] = -1
        } r
    }