/miscellaneous/zero-sum-subarray/main.py

https://github.com/calvinchankf/AlgoDaily · Python · 191 lines · 76 code · 16 blank · 99 comment · 19 complexity · 8dbe8beb0e7a49b54f5cc1024199ff55 MD5 · raw file

  1. """
  2. Given an array, find the subarrays whose elements sum to zero
  3. """
  4. class Solution(object):
  5. def subarraySum(self, nums):
  6. """
  7. :type nums: List[int]
  8. :type k: int <- i made it generic that you to target any other numbers as well
  9. :rtype: [[]]
  10. https://www.youtube.com/watch?v=hLcYp67wCcM
  11. generic approach
  12. - this question is fucking similar to leetcode 325, 525, 560, 930
  13. - find loops <==============================================================
  14. - the basic idea is to store the previous sum in a hashtable
  15. e.g. key: previous sum, value: number of occurence of a previous sum
  16. - if currentSum - target in the hastable, the result+1
  17. Time O(n)
  18. Space O(n)
  19. 7mar2019
  20. """
  21. res = []
  22. acc = 0
  23. # { key: value }
  24. # key: previous sum
  25. # value: array of indeces which previous sum equals to 0
  26. ht = {}
  27. for i in range(len(nums)):
  28. acc += nums[i]
  29. # if acc == 0, it is one of the target subarray
  30. if acc == 0:
  31. res.append(nums[:i+1])
  32. # if acc is in hashtbale, there is a loop
  33. # so there is at least one subarray
  34. if acc in ht:
  35. for j in range(len(ht[acc])):
  36. idx = ht[acc][j]
  37. res.append(nums[idx+1:i+1])
  38. # put the acc into the hashtable with index
  39. # such that we can do slicig later when we found a zero sum asubarray
  40. if acc not in ht:
  41. ht[acc] = [i]
  42. else:
  43. ht[acc].append(i)
  44. return res
  45. # [[-1, 5, -2]]
  46. print(Solution().subarraySum([1, 2, -5, 1, 2, -1]))
  47. print("-----")
  48. """
  49. folloup:
  50. Given an array, find the subarrays whose elements sum to k
  51. """
  52. class Solution(object):
  53. def subarraySum(self, nums, k):
  54. """
  55. :type nums: List[int]
  56. :type k: int <- i made it generic that you to target any other numbers as well
  57. :rtype: [[]]
  58. https://www.youtube.com/watch?v=hLcYp67wCcM
  59. generic approach
  60. - this question is fucking similar to leetcode 325, 560
  61. - the basic idea is to store the previous sum in a hashtable
  62. e.g. key: previous sum, value: number of occurence of a previous sum
  63. - if currentSum - target in the hastable, the result+1
  64. Time O(n)
  65. Space O(n)
  66. 7mar2019
  67. """
  68. res = []
  69. acc = 0
  70. # { key: value }
  71. # key: previous sum
  72. # value: array of indeces which previous sum equals to k
  73. ht = {}
  74. for i in range(len(nums)):
  75. acc += nums[i]
  76. # if acc == k, it is one of the target subarray
  77. if acc == k:
  78. res.append(nums[:i+1])
  79. # if acc-k in hashtable, it is one of the target subarray
  80. if acc-k in ht:
  81. for j in range(len(ht[acc-k])):
  82. idx = ht[acc-k][j]
  83. res.append(nums[idx+1:i+1])
  84. # put the acc into the hashtable
  85. if acc not in ht:
  86. ht[acc] = [i]
  87. else:
  88. ht[acc].append(i)
  89. return res
  90. # [[1], [1], [1]]
  91. print(Solution().subarraySum([1, 1, 1], 1))
  92. # [[1, 1], [1, 1]]
  93. print(Solution().subarraySum([1, 1, 1], 2))
  94. # [[1, 1, 1]]
  95. print(Solution().subarraySum([1, 1, 1], 3))
  96. # [[1, 1, 1], [1, 1, 1]]
  97. print(Solution().subarraySum([1, 1, 1, 1], 3))
  98. # [[1, -1, 5, -2], [5, -2], [3]]
  99. print(Solution().subarraySum([1, -1, 5, -2, 3], 3))
  100. # [[1, -1, 5, -2], [5, -2], [-1, 5, -2, 1], [1, 2]]
  101. print(Solution().subarraySum([1, -1, 5, -2, 1, 2], 3))
  102. # [[-1, 2], [1]]
  103. print(Solution().subarraySum([-2, -1, 2, 1], 1))
  104. # [[-2, -1, 2, 1, 100], [100]]
  105. print(Solution().subarraySum([-2, -1, 2, 1, 100], 100))
  106. # [[100], [-2, -1, 2, 100, 1]]
  107. print(Solution().subarraySum([-2, -1, 2, 100, 1], 100))
  108. # []
  109. print(Solution().subarraySum([-2, -1, 2, 1000], 99))
  110. print("-----")
  111. """
  112. variation: find the longest subarray
  113. """
  114. class Solution(object):
  115. def subarraySum(self, nums, k):
  116. """
  117. :type nums: List[int]
  118. :type k: int <- i made it generic that you to target any other numbers as well
  119. :rtype: [[]]
  120. https://www.youtube.com/watch?v=hLcYp67wCcM
  121. generic approach
  122. - this question is fucking similar to leetcode 325, 560
  123. - the basic idea is to store the previous sum in a hashtable
  124. e.g. key: previous sum, value: number of occurence of a previous sum
  125. - if currentSum - target in the hastable, the result+1
  126. Time O(n)
  127. Space O(n)
  128. 7mar2019
  129. """
  130. res = ""
  131. acc = 0
  132. # { key: value }
  133. # key: previous sum
  134. # value: array of indeces which previous sum equals to k
  135. ht = {}
  136. for i in range(len(nums)):
  137. acc += nums[i]
  138. # if acc == k, it is one of the target subarray
  139. if acc == k:
  140. sub = nums[:i+1]
  141. if len(sub) > len(res):
  142. res = sub
  143. # if acc-k in hashtable, it is one of the target subarray
  144. if acc-k in ht:
  145. idx = ht[acc-k][0]
  146. sub = nums[idx+1:i+1]
  147. if len(sub) > len(res):
  148. res = sub
  149. # put the acc into the hashtable
  150. if acc not in ht:
  151. ht[acc] = [i]
  152. else:
  153. ht[acc].append(i)
  154. return res
  155. # [[1, -1, 5, -2], [5, -2], [3]]
  156. print(Solution().subarraySum([1, -1, 5, -2, 3], 3))
  157. # [[1, -1, 5, -2], [5, -2], [-1, 5, -2, 1], [1, 2]]
  158. print(Solution().subarraySum([1, -1, 5, -2, 1, 2], 3))
  159. # [[-1, 2], [1]]
  160. print(Solution().subarraySum([-2, -1, 2, 1], 1))
  161. # [[-2, -1, 2, 1, 100], [100]]
  162. print(Solution().subarraySum([-2, -1, 2, 1, 100], 100))
  163. # [[100], [-2, -1, 2, 100, 1]]
  164. print(Solution().subarraySum([-2, -1, 2, 100, 1], 100))
  165. # []
  166. print(Solution().subarraySum([-2, -1, 2, 1000], 99))