【问题标题】:Leetcode 3sum needs explanationLeetcode 3sum 需要解释
【发布时间】:2022-06-30 01:22:30
【问题描述】:

我遇到过这个问题:

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

这是最优化的解决方案:

nums = [-22, -5, -4, -2, -1, -1, 0, 1, 2, 11, 11, 22, 100]
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
    if len(nums) < 3:
        return []

    counter = {}
    for i in nums:
        if i not in counter:
            counter[i] = 0    
        counter[i] += 1

    nums = sorted(counter)
    if nums[0] > 0 or nums[-1] < 0:
        return []
    
    output = []
    # find answer with no duplicates within combo
    for i in range(len(nums)-1):
        # search range
        twoSum = -nums[i]
        min_half, max_half = twoSum - nums[-1], twoSum / 2
        l = bisect_left(nums, min_half, i + 1)
        r = bisect_left(nums, max_half, l)
        
        for j in nums[l:r]:
            if twoSum - j in counter:
                output.append([nums[i], j, twoSum - j])

    # find ans with duplicates within combo
    for k in counter:
        if counter[k] > 1:
            if k == 0 and counter[k] >= 3:
                output.append([0, 0, 0])
            elif k != 0 and -2 * k in counter:
                output.append([k, k, -2 * k])
    return output

谁能解释一下原因:

min_half = twoSum - nums[-1]
max_half = twoSum/2

我知道我们需要找到剩余两个数字的范围以及 bisect_left 和 bisect_right 的作用。但是为什么 min_half 和 max_half 那样呢?

【问题讨论】:

  • 也许使用print() 来查看值twoSumnums[-1]min_halfmax_half,也许你会看到它在实际值上是如何工作的——这可能有助于理解它

标签: python


【解决方案1】:

以下代码已被 LC “接受”,并且更具可读性

def is_in_sorted(lst, st, en, val):
  m=st; n=en
  while n-m>1:
    mid = (n+m)//2
    if val < lst[mid]:
      n = mid
    elif val > lst[mid]:
      m = mid
    else:
      return True
  if val==lst[m] or val==lst[n]: return True
  return False


class Solution:
  def threeSum(self, nums: List[int]) -> List[List[int]]:
    if len(nums)>2 and nums[0]==0 and len(set(nums))==1: return [[0,0,0]]
    nums.sort()
    sz = len(nums)
    
    out = set()
    for i in range(sz-2):
      for j in range(i+1,sz-1):
        inter = -(nums[i]+nums[j])
        if not (nums[j+1] <= inter <= nums[sz-1]):
          continue
        if is_in_sorted(nums, j+1, sz-1, inter):
          out.add((nums[i],nums[j],inter))
    
    return list(map(list,sorted(out)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 2020-10-03
    • 2022-01-12
    • 2020-04-24
    • 1970-01-01
    相关资源
    最近更新 更多