Home > Back-end >  Calculate circular shift pairs in a list
Calculate circular shift pairs in a list

Time:10-08

A circular shift moves some of the digits in a number to the beginning of the number, and shifts all other digits forward to the next position. For example, all of the circular shifts of 564 are 564, 645, 456.

Lets say two numbers of equal length a and b are circular pairs if a can become b via circular shifting. Using the example above, the circular pairs of 564 are 645 and 456.

Given an array of positive integers nums, count the number of circular pairs i and j where 0 <= i < j < len(nums)

For example, circular_shifts([13, 5604, 31, 2, 13, 4560, 546, 654, 456]) should return 5. With the pairs being (13, 31), (13, 13), (5604, 4560), (31, 13), (546, 654).

I wrote a brute force solution that saves all circular shifts of a number in a dictionary shifts and for every number num in nums, I check all the following numbers and if a number num2 the same digits as num, I see if num2 is in num's circular shifts. If it is then I added this to the total count.

Unfortunately this algorithm runs too slowly and times out, I'm looking for a faster way to solve this problem can anyone think of optimizations, clever tricks, or other strategies to speed this up?

CodePudding user response:

  1. Replace every number in the array with its greatest cyclic shift. 1234, for example, would become 4123
  2. Count the occurrences of each resulting number
  3. If a number occurs n times, that represents n(n-1)/2 cyclic shift pairs. Add them all up.

CodePudding user response:

Not very elegant as not much time but the following should be faster as does not repeatedly access the list. Shifting is done on string for simplicity.

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)
  • Related