First approach ❎

'''
gyan pelo:
this is same as previous problem, the sorting order don't matter in this problem since the only requirement is that elements are adjacent to each other
at most twice means slow pointer has to jump 2 steps when replacing
what is the condition here to increase the fast pointer
it should be increased if first element is same as second element
but both pointer are starting from 0, so when will one of them increase?
I remember there was no pointer + 1 condition in the previous solution, so what to put here? 
fast pointer should increase if both elements are equal so initially fast pointer will get 1 step ahead 
now next slow pointer should increase if fast pointer finds an element which is not same as slow pointer element, once it finds it slow pointer will move one step ahead and replace that value with slow pointer value, so overwrite the value of slow pointer with fast pointer value and move both one them one step ahead.
What am I missing, is +2 required? or some change in condition?
Should fast pointer be initiated by 1 this time?
Should the loop run one more time?
'''
class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        slow_pointer = fast_pointer = 0
        while fast_pointer < len(nums):
            if nums[fast_pointer] == nums[slow_pointer]:
                fast_pointer += 1
            else:
                nums[slow_pointer+2] = nums[fast_pointer]
                fast_pointer +=1
                slow_pointer +=1
                
        return slow_pointer
        

Attempt 2

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        slow_pointer = 0
        count = 1
        flag = False 
        for fast_pointer in range(1, len(nums)):
            if nums[fast_pointer] == nums[slow_pointer]:
                if not flag: 
                    flag = True
                    slow_pointer += 1
                    nums[slow_pointer], nums[fast_pointer] = nums[fast_pointer], nums[slow_pointer]
                    count += 1
            else:
                flag = False
                slow_pointer += 1
                nums[slow_pointer], nums[fast_pointer] = nums[fast_pointer], nums[slow_pointer]
                count += 1
        return count
 
sol = Solution()
nums = [1, 1, 1, 2, 3, 3, 4]
print(sol.removeDuplicates(nums))

Attempt 3 ✅

class Solution:
    def removeDuplicates(self, nums) -> int:
		# Edge Condition
        if len(nums)< 3: return len(nums)
        
		
        slow_pointer = 2  # Pointer from where we need to replace elements
        for fast_pointer in range(2, len(nums)):
            prev_slow = nums[slow_pointer-2]
		  fast_val = nums[fast_pointer]
            if fast_val != prev_slow:
                nums[slow_pointer] = fast_val
                slow_pointer += 1
        return slow_pointer
 
sol = Solution() 
nums = [1, 1, 1, 2, 3, 3, 4] 
print(sol.removeDuplicates(nums))
  • It is not swapping the numbers, just keeping the last series as number as last number duplicates.
  • This program is same as Remove Duplicates from Sorted Array only difference in condition is that slow pointer has 2 substracted.
  • use_more_variables since it keeps the program descriptive.

Attempt 4