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))
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]
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.
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]]
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))
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]
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.
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]]