0

I have been working on a problem on https://www.lintcode.com/ and I have ran into a problem while doing one of the questions. The problem requires me to write a function with two parameters. A list of nums and a target num. You have to take all instances of the target from the list and move them to the front of the original list and the function cannot have a return value. The length of the list is between 1 and 1000000. You also have to do it within a time limit, which is around 400 milliseconds. I can solve the problem, I can't pass the last test case where the length of the list is 1000000. Does anyone know how I can make my code faster?

Original Problem Description for anyone who still isn't clear:

Current Code:

def MoveTarget(nums, target):
    if len(set(nums)) == 1:
        return nums
    index = [i for i in range(len(nums)) if nums[i] == target]
    for i in index:
        nums.insert(0, nums.pop(i))
     

It works if you do:

def MoveTarget(nums, target): 
    count = 0
    left, right = len(nums) - 1, len(nums) - 1
    
    while left >= 0:
        if nums[left] != target:
            nums[right] = nums[left]
            right -= 1
        else:
            count += 1
        left -= 1
        
    for i in range(count):
        nums[i] = target

but I was wondering if there was another, less complicated way.

CoderTang
  • 460
  • 5
  • 14

2 Answers2

2

Here is a simple and relatively efficient implementation:

def MoveTarget(nums, target):
    n = nums.count(target)
    nums[:] = [target] * n + [e for e in nums if e != target]

It creates a new list with the n target values in the front and append all the other values that are not target. The input list nums is mutated thanks to the expression nums[:] = ....

The solution run in linear time as opposed to the previously proposed implementations (running in quadratic time). Indeed, insert runs in linear time in CPython.

ignassew
  • 83
  • 5
Jérôme Richard
  • 41,678
  • 6
  • 29
  • 59
-1

Your code uses 2 loops. One in:

index = [i for i in range(len(nums)) if nums[i] == target]

And one in:

for i in index:
    nums.insert(0, nums.pop(i))

Instead, you can combine finding the target and moving it to the front of array with only one loop, which will greatly reduce the execution time:

def MoveTarget(nums, target):
    if len(set(nums)) == 1:
        return nums
    for num in nums:
        if num == target:
            nums.insert(0, nums.pop(num))
Jérôme Richard
  • 41,678
  • 6
  • 29
  • 59
ignassew
  • 83
  • 5