2017年8月1日 星期二

LeetCode題解 - 4. Median of Two Sorted Arrays [Hard]

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:
nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:
nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

1. Code:
  1. class Solution(object):
  2. def findMedianSortedArrays(self, nums1, nums2):
  3. """
  4. :type nums1: List[int]
  5. :type nums2: List[int]
  6. :rtype: float
  7. """
  8. i = 0
  9. j = 0
  10. total = len(nums1) + len(nums2)
  11. medium = total // 2
  12. ret_list = []
  13. while (i + j) <= medium:
  14. if i >= len(nums1):
  15. ret_list.append(nums2[j])
  16. j += 1
  17. elif j >= len(nums2):
  18. ret_list.append(nums1[i])
  19. i += 1
  20. elif nums1[i] < nums2[j]:
  21. ret_list.append(nums1[i])
  22. i += 1
  23. else:
  24. ret_list.append(nums2[j])
  25. j += 1
  26. if total % 2 == 0:
  27. return (ret_list[-1] + ret_list[-2]) / 2.0
  28. else:
  29. return ret_list[-1]

心得:
雖然題目要求要O(log(m+n)),還是先照自已的想法打一遍
可以成功送出,看來 LeetCode 只會要求正確解出問題 (很合理)
有空我再想想要怎麼用2分法


2. Code:
  1. class Solution(object):
  2. def findMedianSortedArrays(self, nums1, nums2):
  3. """
  4. :type nums1: List[int]
  5. :type nums2: List[int]
  6. :rtype: float
  7. """
  8. total = len(nums1) + len(nums2)
  9.  
  10. if total % 2 == 1:
  11. return self.findKth(nums1, nums2, (total / 2) + 1)
  12. else:
  13. return (self.findKth(nums1, nums2, total / 2) + self.findKth(nums1, nums2, (total / 2) + 1)) / 2.0
  14.  
  15. def findKth(self, list_a, list_b, k):
  16. """ Finding the K position of two arrays
  17.  
  18. :type list_a: List[int]
  19. :type list_b: List[int]
  20. :type k: int, the K position of list_a and list_b
  21. """
  22. if len(list_a) > len(list_b):
  23. return self.findKth(list_b, list_a, k)
  24. elif len(list_a) == 0:
  25. return list_b[k - 1]
  26. elif k == 1:
  27. return list_a[0] if list_a[0] <= list_b[0] else list_b[0]
  28.  
  29. new_pos_a = (k // 2) if (k // 2) <= len(list_a) else len(list_a)
  30. new_pos_b = (k // 2) if (k // 2) <= len(list_b) else len(list_b)
  31. if list_a[new_pos_a - 1] < list_b[new_pos_b - 1]:
  32. return self.findKth(list_a[new_pos_a:], list_b, k - new_pos_a)
  33. else:
  34. return self.findKth(list_a, list_b[new_pos_b:], k - new_pos_b)

心得:
花了很多時間,約於寫出來了
不過效能卻沒有很好,時間大概都花在建 List 上了吧
花了 98 ms

3. Code:
  1. class Solution(object):
  2. def findMedianSortedArrays(self, nums1, nums2):
  3. """
  4. :type nums1: List[int]
  5. :type nums2: List[int]
  6. :rtype: float
  7. """
  8. total = len(nums1) + len(nums2)
  9. if total % 2 == 1:
  10. return self.findKth(nums1, 0, nums2, 0, (total / 2) + 1)
  11. else:
  12. return (self.findKth(nums1, 0, nums2, 0, total / 2) + self.findKth(nums1, 0, nums2, 0, (total / 2) + 1)) / 2.0
  13. def findKth(self, list_a, pos_a, list_b, pos_b, k):
  14. """ Finding the K position of two arrays
  15. :type list_a: List[int]
  16. :type pos_a: int, the index of list_a
  17. :type list_b: List[int]
  18. :type pos_b: int, the index of list_b
  19. :type k: int, the K position of list_a and list_b
  20. """
  21. if (len(list_a) - pos_a) > (len(list_b) - pos_b):
  22. return self.findKth(list_b, pos_b, list_a, pos_a, k)
  23. elif len(list_a) == pos_a:
  24. return list_b[pos_b + k - 1]
  25. elif k == 1:
  26. return list_a[pos_a] if list_a[pos_a] <= list_b[pos_b] else list_b[pos_b]
  27. new_pos_a = (pos_a + (k // 2)) if (pos_a + (k // 2)) <= len(list_a) else len(list_a)
  28. new_pos_b = pos_b + k - (new_pos_a - pos_a)
  29. if list_a[new_pos_a - 1] < list_b[new_pos_b - 1]:
  30. return self.findKth(list_a, new_pos_a, list_b, pos_b, k - (new_pos_a - pos_a))
  31. elif list_a[new_pos_a - 1] > list_b[new_pos_b - 1]:
  32. return self.findKth(list_a, pos_a, list_b, new_pos_b, k - (new_pos_b - pos_b))
  33. else:
  34. return list_a[new_pos_a - 1]

心得:
如果用 index 代替,會稍微快一點點
不過差距也不大拉



沒有留言:

張貼留言