1

For this Leetcode question, it seems that if I use the following code, it will pass the online judge:

Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

 

Example 1:

Input: nums = [1,5,11,5]
Output: true
Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:

Input: nums = [1,2,3,5]
Output: false
Explanation: The array cannot be partitioned into equal sum subsets.
 

Constraints:

1 <= nums.length <= 200
1 <= nums[i] <= 100

Solution:

class Solution:

def canPartition(self, nums: List[int]) -> bool:

    @cache
    def dp(i, s):
        if s == 0:
            return True
        if i == 0 or s<0:
            return False
        if nums[i]<=s:
            return dp(i-1, s) or dp(i-1, s-nums[i])
        else:
            return dp(i-1, s)
        
    total = sum(nums)
    if total%2 != 0:
        return False
    half = total//2
    return dp(len(nums)-1, half)

However, if I change the or operator in the dp function to |, the algorithm will run into TLE (Time Limited Exceeded), although the answers are still correct:

class Solution:

def canPartition(self, nums: List[int]) -> bool:

    @cache
    def dp(i, s):
        if s == 0:
            return True
        if i == 0 or s<0:
            return False
        if nums[i]<=s:
            return dp(i-1, s) | dp(i-1, s-nums[i])
        else:
            return dp(i-1, s)
        
    total = sum(nums)
    if total%2 != 0:
        return False
    half = total//2
    return dp(len(nums)-1, half)

I know | is meant for binary operations. But does this mean that | is slow if applied to boolean values?

Jinhua Wang
  • 1,679
  • 1
  • 17
  • 44

1 Answers1

0

I think @khelwood and @luk2302 are right. or short circuits, | does not. In other words, or will stop evaluating the second depth-first-search if the first is True, while | always evaluate both, resulting an overly long stack that exploded the memory.

Jinhua Wang
  • 1,679
  • 1
  • 17
  • 44
  • _"resulting an overly long stack that exploded the memory."_ ➡ aka a `StackOverflow`. But in python it results in a `RecursionError`. – aneroid Mar 20 '22 at 09:48