###### tags: `leetcode` # 88. Merge Sorted Array ## Array Style ```python= class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ # array style # pretend that I am playin w/ a real array nums1[n:] = nums1[0:m] # right-shift content of nums1 w/ n elements # nums1[0+n:m+n] = nums1[0:m] i = i1 = i2 = 0 while i1 < m and i2 < n: if nums1[n+i1] <= nums2[i2]: nums1[i] = nums1[n+i1] i1 += 1 i += 1 else: nums1[i] = nums2[i2] i2 += 1 i += 1 if i1 == m: # nums1 is used up. nums1[i:] = nums2[i2:] # For the case where nums2 is used up, we don't have to do anything. # Since nums1 is already there, # we don't need to pour the rest of nums1 to the merged nums1. # They are already there. # So we can ignore the `else` here. # else: # nums1[i:] = nums1[n+i1:] ``` ## Array Style, Better, Don't Need to Copy, Pick the Larger ```python= class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ # array style # pretend that I am playin w/ a real array i = m + n - 1 i1 = m - 1 i2 = n - 1 while i1 >= 0 and i2 >= 0: if nums1[i1] > nums2[i2]: nums1[i] = nums1[i1] i1 -= 1 i -= 1 else: nums1[i] = nums2[i2] i2 -= 1 i -= 1 if i1 < 0: # nums1 is used up. # Pour the rest nums2 to the front side of nums1 nums1[:i+1] = nums2[:i2+1] else: nums1[:i+1] = nums1[:i1+1] ``` ## Python's Linked List Style, Not Accepted But Correct It seems like that Leetcode is checking the content of that reference, not the content of the variable `nums1`. ```python= class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ # python's linked list style nums1_ = nums1[0:m] nums1 = [] # It has a new ref now. # All the modification will be on the new ref. while nums1_ and nums2: if nums1_[0] <= nums2[0]: nums1.append(nums1_.pop(0)) else: nums1.append(nums2.pop(0)) if nums1_: # nums1_ is yet used up. nums1 += nums1_ else: nums1 += nums2 print(nums1) ``` ```python= Wrong Answer Your input [1,2,3,0,0,0] 3 [2,5,6] 3 stdout [1, 2, 2, 3, 5, 6] # the printout is correct Output [1,2,3,0,0,0] # but the data on that ref remain the same Expected [1,2,2,3,5,6] ``` ## Python's Linked List Style, Accepted ```python= class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ # python's linked list style nums1_ = nums1[0:m] tmp = [] while nums1_ and nums2: if nums1_[0] <= nums2[0]: tmp.append(nums1_.pop(0)) else: tmp.append(nums2.pop(0)) if nums1_: # nums1_ is yet used up. tmp += nums1_ else: tmp += nums2 nums1[:] = tmp[:] ``` ## Python's Linked List Style, Accepted, Meaningful ### In Python, **Object references are passed by value**, so it works. ```python= class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ # python's linked list style nums1_ = nums1[0:m] # copy by value tmp = nums1 # copy ref by value nums1 = [] # This var gets a new ref. while nums1_ and nums2: if nums1_[0] <= nums2[0]: nums1.append(nums1_.pop(0)) else: nums1.append(nums2.pop(0)) if nums1_: # nums1_ is yet used up. nums1 += nums1_ else: nums1 += nums2 print(nums1) tmp[:] = nums1[:] # copy by value to the desired ref ``` ## Python's Linked List Style, Accepted, Very Meaningful ### `nums1[:] = []` keeps the ref and clean the contents ```python= class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ # python's linked list style nums1_ = nums1[0:m] nums1[:] = [] # !!! critical !!! while nums1_ and nums2: if nums1_[0] <= nums2[0]: nums1.append(nums1_.pop(0)) else: nums1.append(nums2.pop(0)) if nums1_: # nums1_ is yet used up. nums1 += nums1_ else: nums1 += nums2 ```