Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given an integer array nums.
For any positive integer x, define the following sequence:
p0 = xpi+1 = popcount(pi) for all i >= 0, where popcount(y) is the number of set bits (1's) in the binary representation of y.This sequence will eventually reach the value 1.
The popcount-depth of x is defined as the smallest integer d >= 0 such that pd = 1.
For example, if x = 7 (binary representation "111"). Then, the sequence is: 7 → 3 → 2 → 1, so the popcount-depth of 7 is 3.
You are also given a 2D integer array queries, where each queries[i] is either:
[1, l, r, k] - Determine the number of indices j such that l <= j <= r and the popcount-depth of nums[j] is equal to k.[2, idx, val] - Update nums[idx] to val.Return an integer array answer, where answer[i] is the number of indices for the ith query of type [1, l, r, k].
Example 1:
Input: nums = [2,4], queries = [[1,0,1,1],[2,1,1],[1,0,1,0]]
Output: [2,1]
Explanation:
i |
queries[i] |
nums |
binary(nums) |
popcount- depth |
[l, r] |
k |
Validnums[j] |
updatednums |
Answer |
|---|---|---|---|---|---|---|---|---|---|
| 0 | [1,0,1,1] | [2,4] | [10, 100] | [1, 1] | [0, 1] | 1 | [0, 1] | — | 2 |
| 1 | [2,1,1] | [2,4] | [10, 100] | [1, 1] | — | — | — | [2,1] | — |
| 2 | [1,0,1,0] | [2,1] | [10, 1] | [1, 0] | [0, 1] | 0 | [1] | — | 1 |
Thus, the final answer is [2, 1].
Example 2:
Input: nums = [3,5,6], queries = [[1,0,2,2],[2,1,4],[1,1,2,1],[1,0,1,0]]
Output: [3,1,0]
Explanation:
i |
queries[i] |
nums |
binary(nums) |
popcount- depth |
[l, r] |
k |
Validnums[j] |
updatednums |
Answer |
|---|---|---|---|---|---|---|---|---|---|
| 0 | [1,0,2,2] | [3, 5, 6] | [11, 101, 110] | [2, 2, 2] | [0, 2] | 2 | [0, 1, 2] | — | 3 |
| 1 | [2,1,4] | [3, 5, 6] | [11, 101, 110] | [2, 2, 2] | — | — | — | [3, 4, 6] | — |
| 2 | [1,1,2,1] | [3, 4, 6] | [11, 100, 110] | [2, 1, 2] | [1, 2] | 1 | [1] | — | 1 |
| 3 | [1,0,1,0] | [3, 4, 6] | [11, 100, 110] | [2, 1, 2] | [0, 1] | 0 | [] | — | 0 |
Thus, the final answer is [3, 1, 0].
Example 3:
Input: nums = [1,2], queries = [[1,0,1,1],[2,0,3],[1,0,0,1],[1,0,0,2]]
Output: [1,0,1]
Explanation:
i |
queries[i] |
nums |
binary(nums) |
popcount- depth |
[l, r] |
k |
Validnums[j] |
updatednums |
Answer |
|---|---|---|---|---|---|---|---|---|---|
| 0 | [1,0,1,1] | [1, 2] | [1, 10] | [0, 1] | [0, 1] | 1 | [1] | — | 1 |
| 1 | [2,0,3] | [1, 2] | [1, 10] | [0, 1] | — | — | — | [3, 2] | |
| 2 | [1,0,0,1] | [3, 2] | [11, 10] | [2, 1] | [0, 0] | 1 | [] | — | 0 |
| 3 | [1,0,0,2] | [3, 2] | [11, 10] | [2, 1] | [0, 0] | 2 | [0] | — | 1 |
Thus, the final answer is [1, 0, 1].
Constraints:
1 <= n == nums.length <= 1051 <= nums[i] <= 10151 <= queries.length <= 105queries[i].length == 3 or 4
queries[i] == [1, l, r, k] or,queries[i] == [2, idx, val]0 <= l <= r <= n - 10 <= k <= 50 <= idx <= n - 11 <= val <= 1015Problem summary: You are given an integer array nums. For any positive integer x, define the following sequence: p0 = x pi+1 = popcount(pi) for all i >= 0, where popcount(y) is the number of set bits (1's) in the binary representation of y. This sequence will eventually reach the value 1. The popcount-depth of x is defined as the smallest integer d >= 0 such that pd = 1. For example, if x = 7 (binary representation "111"). Then, the sequence is: 7 → 3 → 2 → 1, so the popcount-depth of 7 is 3. You are also given a 2D integer array queries, where each queries[i] is either: [1, l, r, k] - Determine the number of indices j such that l <= j <= r and the popcount-depth of nums[j] is equal to k. [2, idx, val] - Update nums[idx] to val. Return an integer array answer, where answer[i] is the number of indices for the ith query of type [1, l, r, k].
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Segment Tree
[2,4] [[1,0,1,1],[2,1,1],[1,0,1,0]]
[3,5,6] [[1,0,2,2],[2,1,4],[1,1,2,1],[1,0,1,0]]
[1,2] [[1,0,1,1],[2,0,3],[1,0,0,1],[1,0,0,2]]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
// Auto-generated Java example from go.
class Solution {
public void exampleSolution() {
}
}
// Reference (go):
// // Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
// package main
//
// import "math/bits"
//
// // https://space.bilibili.com/206214
// type fenwick []int
//
// func newFenwickTree(n int) fenwick {
// return make(fenwick, n+1) // 使用下标 1 到 n
// }
//
// // a[i] 增加 val
// // 1 <= i <= n
// // 时间复杂度 O(log n)
// func (f fenwick) update(i int, val int) {
// for ; i < len(f); i += i & -i {
// f[i] += val
// }
// }
//
// // 求前缀和 a[1] + ... + a[i]
// // 1 <= i <= n
// // 时间复杂度 O(log n)
// func (f fenwick) pre(i int) (res int) {
// for ; i > 0; i &= i - 1 {
// res += f[i]
// }
// return
// }
//
// // 求区间和 a[l] + ... + a[r]
// // 1 <= l <= r <= n
// // 时间复杂度 O(log n)
// func (f fenwick) query(l, r int) int {
// return f.pre(r) - f.pre(l-1)
// }
//
// var popDepthList [51]int
//
// func init() {
// for i := 2; i < len(popDepthList); i++ {
// popDepthList[i] = popDepthList[bits.OnesCount(uint(i))] + 1
// }
// }
//
// func popDepth(x uint64) int {
// if x == 1 {
// return 0
// }
// return popDepthList[bits.OnesCount64(x)] + 1
// }
//
// func popcountDepth(nums []int64, queries [][]int64) (ans []int) {
// n := len(nums)
// f := [6]fenwick{}
// for i := range f {
// f[i] = newFenwickTree(n)
// }
// update := func(i, delta int) {
// d := popDepth(uint64(nums[i]))
// f[d].update(i+1, delta)
// }
//
// for i := range n {
// update(i, 1) // 添加
// }
//
// for _, q := range queries {
// if q[0] == 1 {
// ans = append(ans, f[q[3]].query(int(q[1])+1, int(q[2])+1))
// } else {
// i := int(q[1])
// update(i, -1) // 撤销旧的
// nums[i] = q[2]
// update(i, 1) // 添加新的
// }
// }
// return
// }
// Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
package main
import "math/bits"
// https://space.bilibili.com/206214
type fenwick []int
func newFenwickTree(n int) fenwick {
return make(fenwick, n+1) // 使用下标 1 到 n
}
// a[i] 增加 val
// 1 <= i <= n
// 时间复杂度 O(log n)
func (f fenwick) update(i int, val int) {
for ; i < len(f); i += i & -i {
f[i] += val
}
}
// 求前缀和 a[1] + ... + a[i]
// 1 <= i <= n
// 时间复杂度 O(log n)
func (f fenwick) pre(i int) (res int) {
for ; i > 0; i &= i - 1 {
res += f[i]
}
return
}
// 求区间和 a[l] + ... + a[r]
// 1 <= l <= r <= n
// 时间复杂度 O(log n)
func (f fenwick) query(l, r int) int {
return f.pre(r) - f.pre(l-1)
}
var popDepthList [51]int
func init() {
for i := 2; i < len(popDepthList); i++ {
popDepthList[i] = popDepthList[bits.OnesCount(uint(i))] + 1
}
}
func popDepth(x uint64) int {
if x == 1 {
return 0
}
return popDepthList[bits.OnesCount64(x)] + 1
}
func popcountDepth(nums []int64, queries [][]int64) (ans []int) {
n := len(nums)
f := [6]fenwick{}
for i := range f {
f[i] = newFenwickTree(n)
}
update := func(i, delta int) {
d := popDepth(uint64(nums[i]))
f[d].update(i+1, delta)
}
for i := range n {
update(i, 1) // 添加
}
for _, q := range queries {
if q[0] == 1 {
ans = append(ans, f[q[3]].query(int(q[1])+1, int(q[2])+1))
} else {
i := int(q[1])
update(i, -1) // 撤销旧的
nums[i] = q[2]
update(i, 1) // 添加新的
}
}
return
}
# Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
# Time: precompute: O((logr) * log(logr) + log*(r) * (logr)) = O((logr) * log(logr)), r = max(n)
# runtime: O(nlogr + max_k * n + nlogn + qlogn)
# Space: O(logr + max_k * n)
# fenwick tree
def popcount(x):
return bin(x).count('1')
def ceil_log2(x):
return (x-1).bit_length()
class BIT(object): # 0-indexed.
def __init__(self, n):
self.__bit = [0]*(n+1) # Extra one for dummy node.
def add(self, i, val):
i += 1 # Extra one for dummy node.
while i < len(self.__bit):
self.__bit[i] += val
i += (i & -i)
def query(self, i):
i += 1 # Extra one for dummy node.
ret = 0
while i > 0:
ret += self.__bit[i]
i -= (i & -i)
return ret
MAX_N = 10**15
MAX_BIT_LEN = MAX_N.bit_length()
D = [0]*(MAX_BIT_LEN+1)
for i in xrange(2, MAX_BIT_LEN+1):
D[i] = D[popcount(i)]+1
MAX_K = 0
while MAX_N != 1: # O(log*(MAX_N)) times
MAX_N = ceil_log2(MAX_N)
MAX_K += 1
class Solution(object):
def popcountDepth(self, nums, queries):
"""
:type nums: List[int]
:type queries: List[List[int]]
:rtype: List[int]
"""
def count(x):
return D[popcount(x)]+1 if x != 1 else 0
bit = [BIT(len(nums)) for _ in xrange(MAX_K+1)]
for i in xrange(len(nums)):
bit[count(nums[i])].add(i, +1)
result = []
for q in queries:
if q[0] == 1:
_, l, r, k = q
assert(k < len(bit))
result.append(bit[k].query(r)-bit[k].query(l-1))
else:
_, i, x = q
old_d = count(nums[i])
new_d = count(x)
if new_d != old_d:
bit[old_d].add(i, -1)
bit[new_d].add(i, +1)
nums[i] = x
return result
// Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
// Rust example auto-generated from go reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (go):
// // Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
// package main
//
// import "math/bits"
//
// // https://space.bilibili.com/206214
// type fenwick []int
//
// func newFenwickTree(n int) fenwick {
// return make(fenwick, n+1) // 使用下标 1 到 n
// }
//
// // a[i] 增加 val
// // 1 <= i <= n
// // 时间复杂度 O(log n)
// func (f fenwick) update(i int, val int) {
// for ; i < len(f); i += i & -i {
// f[i] += val
// }
// }
//
// // 求前缀和 a[1] + ... + a[i]
// // 1 <= i <= n
// // 时间复杂度 O(log n)
// func (f fenwick) pre(i int) (res int) {
// for ; i > 0; i &= i - 1 {
// res += f[i]
// }
// return
// }
//
// // 求区间和 a[l] + ... + a[r]
// // 1 <= l <= r <= n
// // 时间复杂度 O(log n)
// func (f fenwick) query(l, r int) int {
// return f.pre(r) - f.pre(l-1)
// }
//
// var popDepthList [51]int
//
// func init() {
// for i := 2; i < len(popDepthList); i++ {
// popDepthList[i] = popDepthList[bits.OnesCount(uint(i))] + 1
// }
// }
//
// func popDepth(x uint64) int {
// if x == 1 {
// return 0
// }
// return popDepthList[bits.OnesCount64(x)] + 1
// }
//
// func popcountDepth(nums []int64, queries [][]int64) (ans []int) {
// n := len(nums)
// f := [6]fenwick{}
// for i := range f {
// f[i] = newFenwickTree(n)
// }
// update := func(i, delta int) {
// d := popDepth(uint64(nums[i]))
// f[d].update(i+1, delta)
// }
//
// for i := range n {
// update(i, 1) // 添加
// }
//
// for _, q := range queries {
// if q[0] == 1 {
// ans = append(ans, f[q[3]].query(int(q[1])+1, int(q[2])+1))
// } else {
// i := int(q[1])
// update(i, -1) // 撤销旧的
// nums[i] = q[2]
// update(i, 1) // 添加新的
// }
// }
// return
// }
// Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
// Auto-generated TypeScript example from go.
function exampleSolution(): void {
}
// Reference (go):
// // Accepted solution for LeetCode #3624: Number of Integers With Popcount-Depth Equal to K II
// package main
//
// import "math/bits"
//
// // https://space.bilibili.com/206214
// type fenwick []int
//
// func newFenwickTree(n int) fenwick {
// return make(fenwick, n+1) // 使用下标 1 到 n
// }
//
// // a[i] 增加 val
// // 1 <= i <= n
// // 时间复杂度 O(log n)
// func (f fenwick) update(i int, val int) {
// for ; i < len(f); i += i & -i {
// f[i] += val
// }
// }
//
// // 求前缀和 a[1] + ... + a[i]
// // 1 <= i <= n
// // 时间复杂度 O(log n)
// func (f fenwick) pre(i int) (res int) {
// for ; i > 0; i &= i - 1 {
// res += f[i]
// }
// return
// }
//
// // 求区间和 a[l] + ... + a[r]
// // 1 <= l <= r <= n
// // 时间复杂度 O(log n)
// func (f fenwick) query(l, r int) int {
// return f.pre(r) - f.pre(l-1)
// }
//
// var popDepthList [51]int
//
// func init() {
// for i := 2; i < len(popDepthList); i++ {
// popDepthList[i] = popDepthList[bits.OnesCount(uint(i))] + 1
// }
// }
//
// func popDepth(x uint64) int {
// if x == 1 {
// return 0
// }
// return popDepthList[bits.OnesCount64(x)] + 1
// }
//
// func popcountDepth(nums []int64, queries [][]int64) (ans []int) {
// n := len(nums)
// f := [6]fenwick{}
// for i := range f {
// f[i] = newFenwickTree(n)
// }
// update := func(i, delta int) {
// d := popDepth(uint64(nums[i]))
// f[d].update(i+1, delta)
// }
//
// for i := range n {
// update(i, 1) // 添加
// }
//
// for _, q := range queries {
// if q[0] == 1 {
// ans = append(ans, f[q[3]].query(int(q[1])+1, int(q[2])+1))
// } else {
// i := int(q[1])
// update(i, -1) // 撤销旧的
// nums[i] = q[2]
// update(i, 1) // 添加新的
// }
// }
// return
// }
Use this to step through a reusable interview workflow for this problem.
For each of q queries, scan the entire range to compute the aggregate (sum, min, max). Each range scan takes up to O(n) for a full-array query. With q queries: O(n × q) total. Point updates are O(1) but queries dominate.
Building the tree is O(n). Each query or update traverses O(log n) nodes (tree height). For q queries: O(n + q log n) total. Space is O(4n) ≈ O(n) for the tree array. Lazy propagation adds O(1) per node for deferred updates.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.