我正在努力解决问题K-th Symbol in Grammar - LeetCode
在第一行上,我们写一个
0
。现在,在每个后续行中,我们查看上一行,并用0
替换每次出现的01
,并用1
替换每次出现的10
。Explanation: row 1: 0 row 2: 01 row 3: 0110 row 4: 01101001
我写了这样一个替换函数
def replace(row: "List[int]") -> "List[int]":
"""
rtype: row
"""
for i in range(len(row)):
if row[i] == 0: #0 -> 01
row.insert(i+1, 1)
elif row[i] == 1: #1 -> 10
row.insert(i+1, 0)
return row
但是,它不能正常工作。
In [3]: r2 = replace([0])
In [4]: r2
Out[4]: [0, 1]
In [5]: r3 = replace(r2); print(r3)
[0, 1, 0, 1] # correct is [0, 1, 1, 0]
In [6]: r4 = replace(r3); print(r4)
[0, 1, 0, 1, 0, 1, 0, 1] #correct is ['0', '1', '1', '0', '1', '0', '0', '1']
使用新列表也不起作用。
def replace(row: "List[int]") -> "List[int]":
"""
rtype: row
"""
copy = list(row)
for i in range(len(copy)):
if copy[i] == 0: #0 -> 01
row.insert(i+1, 1)
elif copy[i] == 1: #1 -> 10
row.insert(i+1, 0)
return row
出什么问题了?
答案 0 :(得分:6)
将str.join
与dict
一起使用:
a = '0'
d = {'0': '01', '1': '10'}
# Now run below line only
a = ''.join(d[s] for s in a)
a
输出:
01
0110
01101001
...
答案 1 :(得分:3)
代码的问题在于,您是在循环中将元素插入列表中,而没有考虑列表的长度。
这可以通过添加一个简单的“索引移位器”来解决:
def replace(row: "List[int]") -> "List[int]":
for en, i in enumerate(range(len(row))):
if row[i] == 0: #0 -> 01
row.insert(i+1 + en, 1)
elif row[i] == 1: #1 -> 10
row.insert(i+1 + en, 0)
return row
replace([0, 1, 1, 0])
>>> [0, 1, 1, 0, 1, 0, 0, 1]
一些解释:
我之所以给出这个答案,是因为您问您的代码出了什么问题,并且我想您想或者被要求用这种方法解决此问题。
我不得不说,无论如何,我肯定会采用其他方法:
row
和row[i]
replace([0, 0])
),这确实令人不寒而栗en
变量,在这里它仅用于“教学”目的,因为在这种情况下,它始终为en == i >>> True
更新:
我查看了您提供的link,而您要执行的任务是:
给出第N行和索引K,返回第N行的第K个索引符号。(K的值是1索引)。
具有:
row 1: 0
row 2: 01
row 3: 0110
row 4: 01101001
# etc.
以及以下约束:
N为[1,30]范围内的整数
K将是[1,2 ^(N-1)]范围内的整数
因此,我认为所提出的解决方案都无法与2 ^ 29个元素组成的列表一起使用。
为了解决测验,我们必须更深入一些。
从0
开始,在1
,用01
,10
替换0
和n-th
,基本上是我们的工作迭代,是从n-1-th
扩展具有相同倒排列表的列表,实际上:
def replace(row):
return row + list(map(lambda x: int(not x), row))
replace([0, 1, 1, 0])
>>> [0, 1, 1, 0, 1, 0, 0, 1]
产生正确的输出,这就是您正确的算法起作用的原因。
但是,这仍然不允许您处理N = 2^30
约束。
正如链接中所暗示的那样,递归方法是最好的。
在这里,出于好奇,我给出了一个没有解释的可能解决方案:
def solution(n, k):
if n == 1:
return 0
if k <= 2**(n-1)/2:
return solution(n-1, k)
else:
return 1 - solution(n-1, k-2**(n-1)/2)
`
答案 2 :(得分:2)
仅作为在迭代列表时如何使用另一个列表写入结果的说明:
def replace(row: "List[int]") -> "List[int]":
ret = []
for i in range(len(row)):
if row[i] == 0: #0 -> 01
ret += [0, 1]
elif row[i] == 1: #1 -> 10
ret += [1, 0]
return ret
除非要考虑长度变化,否则在迭代时不应修改iterable。在大多数情况下,创建并列表填充列表会更容易。 结果是:
replace([0,1,1,0])
>>> [0, 1, 1, 0, 1, 0, 0, 1]
答案 3 :(得分:0)
def replace(row: "List[int]") -> "List[int]":
"""
rtype: row
"""
outList = []
for val in row:
if val == 0: #0 -> 01
outList.append(0)
outList.append(1)
elif val == 1: #1 -> 10
outList.append(1)
outList.append(0)
return outList
您的版本在读取列表时对其进行了修改。它的范围仅是原始数组的长度。它只查看两个值,但在第一个0后面插入了1。然后看到了1,导致它又插入了一个0。