The code doesn't always give correct smallest number between the largest and the smallest number that is not in the list

Question:

I have written a code that gives me minimum , maximum and smallest number between the largest and the smallest number that is not in the list.so for few uses cases I do get the correct answer For example. for lt=[2, -4, 8, -5, 9, 7] I got correct answer res=[-5, -3, 9] but for another list pt=[1, 3, -3, -2, 8, -1] is giving me res=[-3, -1, 8] instead of giving res =[-3, 0, 8].

Below is my code:

class Solution(object):

    def minmax(self,nums):
        nums.sort()
        minimum_number = nums[0]
        maximum_number = nums[-1]
        res=[]
        j=1
        count = 0
        for i in range(1,len(nums)):
          while count!=1:
            if minimum_number+j == nums[i]:
                  pass

            else:
                  res.append(minimum_number)
                  res.append(minimum_number + j)
                  res.append(maximum_number)
                  count += 1
            j += 1
        return res

if __name__ == "__main__":
    pt = [2, -4, 8, -5, 9, 7]
    lt = [1, 3, -3, -2, 8, -1]
    print(Solution().minmax(pt))
    print(Solution().minmax(lt))
Asked By: klaus19

||

Answers:

Instead of if minimum_number+j == nums[i]:

do if minimum_number+j in nums:

Also i think no need of for loop..!

Code:

class Solution(object):

    def minmax(self,nums):
        nums.sort()
        minimum_number = nums[0]
        maximum_number = nums[-1]
        res=[]
        j=1
        count = 0
        
        while count!=1:
            if minimum_number+j in nums:
                pass

            else:
                  res.append(minimum_number)
                  res.append(minimum_number + j)
                  res.append(maximum_number)
                  count += 1
            j += 1
        return res

if __name__ == "__main__":
    pt = [2, -4, 8, -5, 9, 7]
    lt = [1, 3, -3, -2, 8, -1]
    print(Solution().minmax(lt))
    print(Solution().minmax(pt))

Output:

[-3, 0, 8]
[-5, -3, 9]
Answered By: Yash Mehta

Currently, your code is only adding the minimum and maximum numbers to the result list, and it is not utilizing the ‘i’ you’re generating.

res.append(minimum_number + j)

should be

res.append(i)

also, the while loop is not necessary.

also, the for loop can start from the min number if you know it already.

Answered By: Unu

I actually have a hard time understanding what your code does. To understand why your code is failing for the second test case, it can be helpful to add some print statements, like this:

    def minmax(self, nums):
        nums.sort()
        minimum_number = nums[0]
        maximum_number = nums[-1]
        res = []
        j = 1
        count = 0
        print(f'nums = {nums}')  # added debug print statement
        for i in range(1, len(nums)):
            print(f'i={i}')  # added debug print statement
            while count != 1:
                print(f'i={i}, j={j}, count={count}')  # added debug print statement
                if minimum_number + j == nums[i]:
                    pass
                else:
                    print('result defined here!')  # added debug print statement
                    res.append(minimum_number)
                    res.append(minimum_number + j)
                    res.append(maximum_number)
                    count += 1
                j += 1
        return res

For your second test case, the output is as follows:

nums = [-3, -2, -1, 1, 3, 8]
i=1
i=1, j=1, count=0
i=1, j=2, count=0
result defined here!
i=2
i=3
i=4
i=5

So the result (variable res) is determined when i=1 and j=2, because nums[1] != minimum_number + 2 (i.e. -2 != -3 + 2). This logic seems flawed. It is probably pure luck (or bad luck) that the code gives correct results for the first testcase.

The code is supposed to find "the smallest number between the largest and the smallest number that is not in the list". So in case the smallest number is -3, you could compare the sorted list with [-3, -2, -1, 0, 1, ...] and find the first number that differs from that list. This can be done using only one index (i), which is much easier than using two indices (i and j). Also, the count variable is unneeded: you do not actually count anything, but are simply using it as a flag. Maybe you are used to such constructs from other programming languages? Using return avoids the need of such extra variables, which makes the code much shorter and clearer IMHO.

Taking the above into account would result in something like this:

class Solution:

    def minmax(self, nums):
        nums.sort()
        for i, num in enumerate(nums):
            if nums[0] + i != num:
                return [nums[0], nums[0] + i, nums[-1]]
        return []

The last line is not really needed, but keeps the behavior similar to your original code. If the last line is removed, the function will return None if no valid solution is found.

Another way to look at the problem is to find the first number that is not exactly 1 higher than the previous number in the list. Following that logic, the inner loop could be written like this (which gives the same result):

        for i in range(len(nums) - 1):
            if nums[i + 1] - nums[i] != 1:
                return [nums[0], nums[i] + 1, nums[-1]]
Answered By: wovano
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.