python - 序列中的第 N 个 1

标签 python python-3.x algorithm

<分区>

长度为 t 的数组的所有元素都由 1 初始化。现在我们可以对数组执行两种类型的查询

  1. 将第 i 索引处的元素替换为 0 。此查询由 0 索引表示
  2. 查找并在新行打印一个整数,表示数组 A 中第 k 个 1 的索引;如果不存在这样的索引,则打印 -1。此查询由 1 k 表示

现在假设对于长度为 t=4 的数组,其开头的所有元素都是 [1,1,1,1] 现在用于查询 0 2 数组变为 [1,0,1,1] 并且查询 1 3 输出结果为 4/p>

我使用了蛮力方法,但如何使代码更高效?

n,q=4,2
arr=[1]*4
for i in range(q):
    a,b=map(int,input().split())
    if a==0:
        arr[b-1]=0
    else:
        flag=True
        count=0
        target=b
        for i,j in enumerate(arr):
            if j ==1:
                count+=1
                if count==target:
                    print(i+1)
                    flag=False
                    break
        if flag:
            print(-1)

我也尝试过先将 1 的所有索引附加到列表中,然后进行二分查找,但是 pop 0 更改了索引,导致代码失败

def binary_search(low,high,b):
    while(low<=high):
        mid=((high+low)//2)
        #print(mid)
        if mid+1==b:
           print(stack[mid]+1)
           return
        elif mid+1>b:
            high=mid-1
        else:
            low=mid+1


n=int(input())
q=int(input())
stack=list(range(n))
for i in range(q):
    a,b=map(int,input().split())
    if a==0:
        stack.pop(b-1)
        print(stack)

    else:
        if len(stack)<b:
            print(-1)
            continue
        else:
            low=0
            high=len(stack)-1
            binary_search(low,high,b)

最佳答案

您可以构建一棵二叉树,其中每个节点都会为您提供其下方和左侧节点的数量。所以如果 n 是 7,那棵树最初看起来像这样(下面显示了所有的实际列表):

         4
      /    \
    2        2
   / \      / \
  1   1    1   1
 ----------------
 1 1 1 1  1 1 1 -

将索引 4(从零开始)处的数组元素设置为 0,会将树更改为:

         4
      /    \
    2        1*
   / \      / \
  1   1    0*  1
 ----------------
 1 1 1 1  0*1 1 -

因此,输入 0 表示 O(log(n)) 时间复杂度。

计算 1 的数量也可以在相同的时间复杂度下完成,方法是在沿正确的方向沿着树下降的同时对节点值求和。

这是您可以使用的 Python 代码。它代表 list in breadth-first order 中的树.我没有费尽心思进一步优化代码,但它具有上述时间复杂度:

class Ones:
    def __init__(self, n): # O(n)
        self.lst = [1] * n
        self.one_count = n
        self.tree = []
        self.size = 1 << (n-1).bit_length()
        at_left = self.size // 2
        width = 1
        while width <= at_left:
            self.tree.extend([at_left//width] * width)
            width *= 2

    def clear_index(self, i): # O(logn)
        if i >= len(self.lst) or self.lst[i] == 0:
            return
        self.one_count -= 1
        self.lst[i] = 0        
        # Update tree 
        j = 0
        bit = self.size >> 1
        while bit >= 1:
            go_right = (i & bit) > 0
            if not go_right:
                self.tree[j] -= 1
            j = j*2 + 1 + go_right
            bit >>= 1

    def get_index_of_ith_one(self, num_ones): # O(logn)
        if num_ones <= 0 or num_ones > self.one_count:
            return -1
        j = 0
        k = 0
        bit = self.size >> 1
        while bit >= 1:
            go_right = num_ones > self.tree[j]
            if go_right:
                k |= bit
                num_ones -= self.tree[j]
            j = j*2 + 1 + go_right
            bit >>= 1
        return k

    def is_consistent(self): # Only for debugging
        # Check that list can be derived by calling get_index_of_ith_one for all i 
        lst = [0] * len(self.lst)
        for i in range(1, self.one_count+1):
            lst[self.get_index_of_ith_one(i)] = 1
        return lst == self.lst

# Example use
ones = Ones(12)
print('tree', ones.tree)
ones.clear_index(5)
ones.clear_index(2)
ones.clear_index(1)
ones.clear_index(10)
print('tree', ones.tree)
print('lst', ones.lst)
print('consistent = ', ones.is_consistent())

请注意,这会将索引视为从零开始的索引,而方法 get_index_of_ith_one 需要一个至少为 1 的参数(但它会返回一个从零开始的索引)。

它应该很容易适应您的需求。

复杂度

  • 创建:O(n)
  • 清除索引:O(logn)
  • 获取一个的索引:O(logn)
  • 空间复杂度:O(n)

关于python - 序列中的第 N 个 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48244991/

相关文章:

python - 为什么我的当前目录没有出现在 Windows 上使用 pytest 的路径中?

python - 在 python 中拆分一组大写字母

python - Pytest 项目运行速度很慢

c++ - 如何统计long long类型变量的位数?

java - 基于定时器遍历树

sql - 如何更改历史表上的历史数据

python - python如何计算列表中的 'max'元素?

python - 从数千个列头中删除 '.' [python]

python-3.x - Python 3 的进程之间共享多维数组

python - 在 Python 中分隔字符串,排除一些包含分隔符的元素