问题在这里。输入是一个整数列表。如果三个相邻的数字相邻出现,它们应该被删除,并再次进行操作。Iphone应用程序,有相同颜色的球。输出应该是将被销毁的球的计数。
的例子:
input = [3,3,4,4,4,3,4]
1日迭代
output: [3,3,3,4]
最终输出:
6
第一次迭代时4,4,4,所以有三个球。第二个是3 3 3。六。
我的代码如下。它将删除4,4,4,但之后会失败,因为列表索引将很快超出范围。
def balls(a):
curr_index = 0
removed_count = 0
while len(a) > 2:
if (a[curr_index] == a[curr_index+1]) and (a[curr_index] == a[curr_index+2]):
a.remove(a[curr_index])
a.remove(a[curr_index+1])
a.remove(a[curr_index+2])
curr_index += 1
removed_count += 3
return removed_count
a = [3, 3, 4, 4, 4, 3, 4]
print(balls(a)) # should print 6
任何想法?
input_values = [3,3,4,4,4,3,4]
values = input_values
while len(values) >= 3:
for x in range(0,len(values)-2):
# if we find 3 values in ar row
if values[x] == values[x+1] and values[x] == values[x+2]:
# update values by cutting out the series
values = values[:x] + values[x+3:]
# break this for loop
break
else:
# for loops can have an else statement
# this means that we came at the end of the for loop
# this if we didn't break the loop (and didn't found a valid triple)
# then we brea
break
#result - amount of removed balls
values, len(input_values) - len(values)
一个更通用的方法,你可以定义N
(它将找到精确的N个值)
input_values = [3,3,4,4,4,4,3,3,4]
# amount of neighbours
N = 4
values = input_values
# keep looping as long as we've N values
while len(values) >= N:
# we need this if we break the inner loop
stop = False
# loop over values from left to right
# 3 -> 3 -> 4 -> 4 -> ... until -N + 1
# because that is the last spot that we've N values left
for x in range(0, len(values) - N + 1):
# scout for the next numbers (x+1 x+2 x+3 ....)
# this goes from, x+1 until the end of the serie
# also start counting from 2 - because
# if we've a single match, 2 numbers are equal
for e, y in enumerate(range(x+1, len(values)), start=2):
# if x and y are different, the stop this scouting
# remember y = x+1 x+2 x+3 ....
if values[x] != values[y]:
break
# if we reached this stage, we know that
# x and x+1 x+2 ... are equal
# but also check if we've enough matches
if e == N:
# update values by cutting out the series
values = values[:x] + values[y+1:]
stop = True
break
if stop:
break
else:
# for loops can have an else statement
# this means that we came at the end of the for loop
# this if we didn't break the loop (and didn't found a valid triple)
# then we brea
break
values, len(input_values) - len(values)
有一种方法:
your_list=[3, 3, 4, 4, 4, 3, 4]
def remove_one(l):
if len(l)>2:
for i in range(len(l)-2):
if l[i]==l[i+1]==l[i+2]:
res.extend(l[i:i+3])
l=l[:i]+l[i+3:]
return l
return []
res=[]
while len(your_list)>2:
your_list=remove_one(your_list)
print(len(res))
输出:
6
具有最小阈值的方法
input_values = [3,3,4,4,4,4,4,3,3,4]
# threshold
N = 3
values = input_values
while len(values) >= N:
# we need this if we break the inner loop
stop = False
# loop over values
for x in range(0, len(values) - N + 1):
# scout for the next numbers (x+1 x+2 x+3 ....)
for e, y in enumerate(range(x+1, len(values)), start=2):
# check if the values of x and x+1 (x+2 x+3 ...) are different
if values[x] != values[y]:
# if so, check if we've reached our threshold of N
if e >= N:
# if this is the case update values by cutting out the series
values = values[:x] + values[y:]
stop = True
break
# if x+n != x then we break this scouting loop
break
# stop is True, this means, that we found N neibouring numbers
# thus we can break this loop, and start over with a new* value
if stop:
break
else:
# for loops can have an else statement
# this means that we came at the end of the for loop
# thus if we didn't break the loop (and didn't found a valid triple)
# then we break
break
values, len(input_values) - len(values)
你的代码有几个问题。
第一个是你试图在列表上迭代一次,但这对你的例子不起作用。
第二种情况是你假设列表总是减少到小于3,如果你有更多的数字,情况就不会是这样了。
还有一些地方可以简化语法,例如:
if (a[curr_index] == a[curr_index+1]) and (a[curr_index] == a[curr_index+2]):
等价于:
if a[curr_index] == a[curr_index + 1] == a[curr_index + 2]:
和
a.remove(a[curr_index])
a.remove(a[curr_index+1])
a.remove(a[curr_index+2])
等价于:
del a[curr_index: curr_index + 3]
这里有一种方法可以做到这一点,尽管有更有效的方法。
def balls(a):
removed = 0
complete = False
# Run until complete is set or the list is too short for a match
while not complete and len(a) >= 3:
for idx, val in enumerate(a):
if val == a[idx + 1] == a[idx + 2]:
del a[idx: idx + 3]
removed += 3
break # Restart every time we find a match
# If it's the last possible match, set complete
if idx == len(a) - 3:
complete = True
break
return removed
我有点晚了,但我的想法是一次完成处理。这个想法是,当你删除一个三元组时,返回两个位置来重新检查是否通过该更改创建了一个新的三元组。
的例子:
3 3 4 4 4 3
^--- tripple found here, remove it
3 3 3
^--- move the cursor 2 positions left and continue checking
代码:
def drop3(lst):
# drop3 destroys the lst, make a copy if you want to keep it
dropped = 0
cursor = 0
limit = len(lst) - 2
while cursor < limit:
if lst[cursor] == lst[cursor+1] == lst[cursor+2]:
del lst[cursor:cursor+3]
cursor = max(0, cursor-2)
limit -= 3
dropped += 3
else:
cursor += 1
return dropped
线性时间解:
def balls(a):
b = []
for x in a:
b.append(x)
if b[-3:] == [x] * 3:
del b[-3:]
return len(a) - len(b)