2021-12-30:分裂问题。 一个数n,可以分裂成一个数组[n/2, n%2, n/2], 这个数组中哪个数不是1或者0,就继续分裂下去。 比如 n = 5,一开始分裂成[2, 1, 2], [2
Posted 福大大架构师每日一题
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-12-30:分裂问题。 一个数n,可以分裂成一个数组[n/2, n%2, n/2], 这个数组中哪个数不是1或者0,就继续分裂下去。 比如 n = 5,一开始分裂成[2, 1, 2], [2相关的知识,希望对你有一定的参考价值。
2021-12-30:分裂问题。
一个数n,可以分裂成一个数组[n/2, n%2, n/2],
这个数组中哪个数不是1或者0,就继续分裂下去。
比如 n = 5,一开始分裂成[2, 1, 2],
[2, 1, 2]这个数组中不是1或者0的数,会继续分裂下去,比如两个2就继续分裂,
[2, 1, 2] -> [1, 0, 1, 1, 1, 0, 1],
那么我们说,5最后分裂成[1, 0, 1, 1, 1, 0, 1]。
每一个数都可以这么分裂,在最终分裂的数组中,假设下标从1开始,
给定三个数n、l、r,返回n的最终分裂数组里[l,r]范围上有几个1。
n <= 2 ^ 50,n是long类型,
r - l <= 50000,l和r是int类型。
我们的课加个码:
n是long类型随意多大都行,
l和r也是long类型随意多大都行,但要保证l<=r。
来自腾讯。
答案2021-12-31:
每次裂变都放到map中。
时间复杂度:O(logN)。
空间复杂度:O(logN)。
代码用golang编写。代码如下:
package main
import "fmt"
func main()
ret := nums2(5, 4, 7)
fmt.Println(ret)
func nums2(n, l, r int) int
allMap := make(map[int]int)
return dp(n, l, r, allMap)
func size(n int) int
if n == 1 || n == 0
return 1
else
half := size(n / 2)
return (half << 1) + 1
func dp(n, l, r int, allMap map[int]int) int
if n == 1 || n == 0
return twoSelectOne(n == 1, 1, 0)
half := size(n / 2)
all := (half << 1) + 1
mid := n & 1
if l == 1 && r >= all
if _, ok := allMap[n]; ok
return allMap[n]
else
count := dp(n/2, 1, half, allMap)
ans := (count << 1) + mid
allMap[n] = ans
return ans
else
mid = twoSelectOne((l > half+1 || r < half+1), 0, mid)
left := twoSelectOne(l > half, 0, dp(n/2, l, getMin(half, r), allMap))
right := twoSelectOne(r > half+1, dp(n/2, getMax(l-half-1, 1), r-half-1, allMap), 0)
return left + mid + right
func twoSelectOne(c bool, a, b int) int
if c
return a
else
return b
func getMax(a, b int) int
if a > b
return a
else
return b
func getMin(a, b int) int
if a < b
return a
else
return b
执行结果如下:
以上是关于2021-12-30:分裂问题。 一个数n,可以分裂成一个数组[n/2, n%2, n/2], 这个数组中哪个数不是1或者0,就继续分裂下去。 比如 n = 5,一开始分裂成[2, 1, 2], [2的主要内容,如果未能解决你的问题,请参考以下文章