简体   繁体   中英

Python time complexity

This program is for competition. but it exceeds the time. so is there any way i can make this code run faster. And if you can suggest how to print 2-D list efficiently in python. and i want to print int from that 2-D list. link of the detailed program description: https://www.codechef.com/MAY20B/problems/TRPLSRT

  for i in range(int(input())):
   N,K = map(int,input().split())
   arr=list(map(int,input().split()))
   shift = []
   shiftList = []
   temp = 0
   c = 0
   while(c < K):
      c += 1
      for i in range(len(arr)):
         if(arr[i] != (i+1) ):
            shift.append(i)
            if(len(shift)==3):
               shiftList.append(shift)
               temp = arr[shift[-1]]
               arr[shift[-1]] = arr[shift[-2]]
               arr[shift[-2]] = arr[shift[-3]]
               arr[shift[-3]] = temp
               shift = []
               break

   if(arr == sorted(arr)):   
      print(len(shiftList))
      for i in range(len(shiftList)):
         for j in range(len(shiftList[i])):
            print(shiftList[i][j] + 1,end=" ")
         print()   
   else:
      print(-1)

The for i in range(len(arr)) part of the code can be simplified but I believe that is not the problem causing excessive run time.

You should avoid going through the list from the beginning at each iteration. When you find your first "unsorted" index, you should keep track of it so that, on the next pass, you start the process from there rather than starting at index zero each time. This should cut down on unnecessary looping as you progressively sort the array.

Secondly, the problem statement doesn't require the indexes to be increasing order so you can select any 3 indexes in the list. The best strategy would be to pick the 3 indexes so that the shifting operation places at least two values at their appropriate position:

  • i1 should be the first non-sorted position
  • i2 should be index where the appropriate value of i1 is located. It will be at an index > i1 since i1 is the first non-sorted position
  • i3 should be the index where the appropriate value of i2 is located. this one is a bit trickier because you may have passed that position when you reach the index you want for i2. So there are two possibilities:
  • a) the value for i2 is farther away than i2: Just use it when you find it
  • b) the value for i2 was before i2: use the last index you found between i1 and i2 and let this resolve itself on the next pass

.

def shift3(K,p):
    lasti = 0
    for _ in range(K):
         i1 = i2 = i3 = None
         for i in range(lasti,len(p)):
             print(i,i1,i2,i3)
             if p[i] == i+1:                       # find next unsorted position
                continue
             if i1 is None:                        # use first unsorted position as i1
                lasti = i1 = i                     # also record highest sorted position
                continue
             if p[i] == i1+1:                      # i2 is position of element that should be at i1
                 i2 = i
             if i3 is None or p[i] == i2+1:        # i3 is position of i2 element (if possible)
                 i3 = i
             if i2 is not None and i3 is not None: # perform shift
                 p[i1],p[i2],p[i3] = p[i2],p[i3],p[i1]
                 break

x = [1,7,3,2,4,6,5]
shift3(5,x)
print(x)
# [1, 2, 3, 4, 5, 6, 7]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM