[英]Calculate circular shift pairs in a list
循環移位將數字中的一些數字移動到數字的開頭,並將所有其他數字向前移動到下一個 position。例如,564 的所有循環移位都是564
564, 645, 456
。
假設兩個長度相等的數字a
和b
是循環對,如果a
可以通過循環移位變成b
。 使用上面的示例,循環對564
是645
和456
。
給定一個正整數數組nums
,計算循環對i
和j
的數量,其中0 <= i < j < len(nums)
例如, circular_shifts([13, 5604, 31, 2, 13, 4560, 546, 654, 456])
應該返回5
。 對是(13, 31), (13, 13), (5604, 4560), (31, 13), (546, 654)
。
我寫了一個蠻力解決方案,將數字的所有循環移位保存在字典shifts
中,對於nums
中的每個數字num
,我檢查以下所有數字,如果數字num2
與num
的數字相同,我看看num2
是否在num
中的循環移位。 如果是,那么我將其添加到總數中。
不幸的是,這個算法運行得太慢而且會超時,我正在尋找一種更快的方法來解決這個問題,有人能想到優化、巧妙的技巧或其他加速這個問題的策略嗎?
由於時間不多,不是很優雅,但是由於不重復訪問列表,因此以下應該會更快。 為簡單起見,移位是在字符串上完成的。
from collections import Counter
def big(num):
max = num
s = str(num)
for _ in s:
x = int(s[-1] + s[0:-1])
if x > max:
max = x
return max
circs = [big(z) for z in mylist]
c = Counter(circs)
total = 0
for i in c:
if c[i] > 1:
total += c[i]
print(total)
這是我的解決方案,我們
numbers = [13, 5604, 31, 2, 13, 4560, 546, 654, 456]
# shift_pairs = [(13,31),(13,13),(5604,4560),(31,13),(546,654)]
pairsFound = 0
for i in range(len(numbers)):
number = numbers[i]
length = len(str(number))
numberToRotate = number
shift_remaining = length - 1
temp_list = numbers[i+1:]
while(shift_remaining >= 0):
t_remainder = numberToRotate % 10 # 4
numberToRotate = numberToRotate // 10 # 560
numberToRotate = numberToRotate + t_remainder * 10 **(length-1) # 4560
# we should also check for length for cases like 4560, where on a shift we get 456
if(numberToRotate in temp_list and len(str(numberToRotate)) == length):
print("({},{})".format(number,numberToRotate))
pairsFound += 1
shift_remaining -= 1
print("no of pairs:", pairsFound)
output
(13,31)
(13,13)
(5604,4560)
(31,13)
(546,654)
no of pairs: 5
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.