How do I get smallest postitive integer not present in the array - python

I am trying to find out smallest positive number not present in the list a
def smallitem(a):
a = sorted(set(a))
lst = []
for item in a:
item + = 1
if item not in a:
lst.append(item)
continue
mst = []
for item in lst:
if item < 1:
item += 1
if item not in a:
mst.append(item)
continue
n = 0
if mst:
n = min(mst)
return n or min(lst)
I think I have got the solution but it doesnt look correct to me the way I have done it.
for example:
smallitem([-1, -3]) # 1
smallitem([1,3,6,4,1,2, 87]) # 5

You can convert the list to a set and then keep incrementing a positive integer from 1 until it is not found in the set:
def smallitem(a):
set_a = set(a)
i = 1
while i in set_a:
i += 1
return i

Perhaps there's a lighter way do this.
The time complexity is always O(n).
def small_item(a):
s = set(a)
for i in range(1, max(s)):
if i not in s:
return i
return max(max(s) + 1, 1)
print small_item([1,3,6,4,1,2, 87])
print small_item([-1, -3])

Here's anther way to do this:
def smallitem(l):
l = list(set(sorted(l)))
x = l[0]
for i in l:
if i != x and x >= 1:return x
x += 1
return 1
Testing:
>>> smallitem([-3, -1])
1
>>> smallitem([1, 3, 6, 4, 1, 2, 87])
5
>>>

Related

Given an array of N integers, and an integer K, find the number of pairs of elements in the array whose sum is equal to K

Problem Statement:- Given an array of N integers, and an integer K, find the number of pairs of elements in the array whose sum is equal to K.
**def countpairs(x,length,sum):
count = 0
for i in range(0,length):
for j in range(i+1,length):
print(x[i],x[j])
if(x[i]+x[j]==sum):
count+=1
print(count)
x = [1, 1, 1, 1]
sum = 2
length=len(x)
countpairs(x,length,sum)
Output:= 6**
This is My solution used in VS code.
My Question:- whenever I am running the same code in gfg it is not accepting the code giving me this error. I even have tried the same code in the online compiler there also it is running correctly.
This Is the gfg code which i have written
class Solution:
def getPairsCount(self, arr, K, N):
count = 0
for i in range(0,N):
for j in range(i+1,N):
if(arr[i]+arr[j]==K):
count+=1
return count
#Initial Template for Python 3
if __name__ == '__main__':
tc = int(input())
while tc > 0:
n, k = list(map(int, input().strip().split()))
arr = list(map(int, input().strip().split()))
ob = Solution()
ans = ob.getPairsCount(arr, n, k)
print(ans)
tc -= 1
Error
if(arr[i]+arr[j]==K):
IndexError: list index out of range
There's no added value in using a class for this. You just need:-
def getPairsCount(arr, K):
count = 0
for i in range(len(arr)-1):
if arr[i] + arr[i+1] == K:
count += 1
return count
EDIT:
Previous answer assumed that only adjacent elements were to be considered. If that's not the case then try this:-
import itertools
def getPairsCount(arr, K):
count = 0
for c in itertools.combinations(sorted(arr), 2):
if c[0] + c[1] == K:
count += 1
return count
data = [1, 2, 1, 4, -1]
print(getPairsCount(data, 3))
We do not need two loops for this question. Here is something that runs in O(n):
def countpairs(list_,K):
count = 0
set_ = set(list_)
pairs_ = []
for val in list_:
if K - val in set_:
# we ensure that pairs are unordered by using min and max
pairs_.append ( (min(val, K-val), max(val, K-val)) )
count+=1
set_pairs = set(pairs_)
print ("Pairs which sum up to ",K," are: ", set_pairs)
return len(set_pairs)
x = [1,4,5,8,2,0,24,7,6]
sum_ = 13
print ("Total count of pairs summming up to ", sum_, " = ", countpairs(x, sum_))
Output:
Pairs which sum up to 13 are: {(6, 7), (5, 8)}
Total count of pairs summming up to 13 = 2
The idea is that if two values should sum to a value K, we can iterate through the array and check if there is another element in the array which when paired with the current element, sums up to K. The inner loop in your solution can be replaced with a search using the in. Now, we need this search to be fast (O(1) per element), so we create a set out of our input array (set_ in my example).
def solve(a,K):
freq = {}
for v in a:
if v in freq:
freq[v] += 1
else:
freq[v] = 1
for i in range(len(set(a))):
res += freq[a[i]] * freq[K - a[i]]
return res
a = [int(v) for v in input().split()]
K = int(input())
print(solve(a,K))
# Time Complexity : O(N)
# Space Complexity : O(1)
def solve(a,K):
freq = {}
for v in a:
if v in freq:
freq[v] += 1
else:
freq[v] = 1
for i in range(len(set(a))):
res += freq[a[i]] * freq[K - a[i]]
return res
a = [int(v) for v in input().split()]
K = int(input())
print(solve(a,K))

How to compare two lists according to a specific requirement?

I have a reference list my_ref = [1,2,3]. I am trying to create a function foo that takes a list of length 3 (let's call it list_n). foo will check if adding just value 1 to only one arbitrary element of list_n, makes each element of list_n be greater than each element of my_ref pairwise. Since this explanation may be confusing, I present several examples as follows:
Example 1:
my_ref = [1,2,3]
list1 = [0,2,4]
If number 1 is added to one of the zeroes, then we have [0,2,4], so now all elements of list1 are greater than equal to all greatest elements of my_list, i.e. 1 = 1, 2=2 and 4 > 3. So the function should return True with that element to be added by 1, which was 0 in this example.
Example 2:
my_ref = [1,2,3]
list_2 = [2,2,1]
If number 1 is added to one of the two's, then we have [3,2,1], so all elements of list1 are greater than equal to all elements of my_list, i.e. 3 = 3, 2=2 and 1 = 1. Therefore, the function should return True with that element to be added by 1, which was 2 in this example.
Example 3:
my_ref = [1,2,3]
list_3 = [5,3,1]
By adding number 1 to any one's of list_3, we will have: 5>3, 3>2, 2>1. Hence, the function returns True with the number 1.
BUT
Example 4:
my_ref = [1,2,3]
list_3 = [0,2,1]
There is no way to add number 1 to any elements of list_3 so that the explained requirement is met. Thus, the function should return False with None.
I have coded as follows:
def fun(l):
my_ref = [1, 2, 3]
l.sort()
for i in range(2, 0, -1):
if l[i] < ref[i] and sum(l) >= 5:
return True, l[i]
return False, None
It works fine with most examples but not all. For instance, print(fun([4, 1, 0])) returns (True, 1) which is wrong, instead it should return (False, None). I have tried a lot. Each time, the function with some examples work fine but with some examples doesn't. I hope my the problem is now clear.
How do I fix it?
Thank you.
def func(l):
superior = 0
ref = [0, 1, 2, 3]
l1 = l[:]
l2 = l[:]
l3 = l[:]
l4 = l[:]
l1[0]+=1
l2[1]+=1
l3[2]+=1
l4[3]+=1
targets = [l1, l2, l3, l4]
for i in range(len(targets)):
if get_superior_count(targets[i]) >= 3:
return True, i
return False, None
def get_superior_count(l):
ref = [0, 1, 2, 3]
target = l[:]
count = 0
l.sort()
m = 3
n = 3
while m > 0 and n > 0:
if target[m] >= ref[n]:
count+=1
target.pop(m)
ref.pop(n)
m-=1
n-=1
return count
Not sure it is what you want (and it's a bit ugly) but seems working with your examples.
def checker(my_ref, l):
if sum(l) +1 < sum(my_ref):
return False
return True
def align_lists(my_ref, l):
return list(zip(sorted(my_ref), sorted(l)))
def compare_paired_elements(l, my_ref):
requires_bump = 0
if not checker(my_ref, l):
return False
for pair in align_lists(my_ref, l):
ref_num = pair[0]
num = pair[1]
if num < ref_num:
if num + 1 < ref_num:
continue
if num + 1 == ref_num:
requires_bump += 1
print(num, "needs a bump to match", ref_num)
if requires_bump > 1:
return False
else:
return True
Examples:
> my_ref = [1,2,3]
> l = [0,2,4]
> compare_paired_elements(l, my_ref)
0 needs a bump to match 1
True
> l = [4,1,0]
> compare_paired_elements(l, my_ref)
0 needs a bump to match 1
1 needs a bump to match 2
False

Print the length of the longest continuous sequence of alternating odd and even numbers

How would I go about reading integers until -1 is input and then printing the length of the longest continuous sequence of numbers where there are
alternating odd then even numbers?
I've achieved the first section but it went downhill from there.
Some testing lists:
[1,2,3,4,5,10,6,7,8,20,25,30,40,-1]
[6,7,8,20,25,30,40,1,2,3,4,5,10,15,20,-1]
Here is my code:
evenOdd=[]
while True:
try:
n=int(input())
if n != -1:
evenOdd.append(n)
except:
break
evenOdd=[]
longest = 0
length = 0
for i in range(len(evenOdd)):
if ((evenOdd[i-2]% 2 == 0) and (evenOdd[i-1]% 2 == 1) and (evenOdd[i]% 2 == 0):
length += 1
else:
longest = max(longest, length)
length = 0
print(longest)
One option would be to keep track of the longest sequence as you go:
longest = []
current = []
while True:
n = int(input("Enter value: "))
if n == -1:
break
if current and current[-1] % 2 != n % 2:
current.append(n)
else:
current = [n]
if len(current) > len(longest):
longest = current
The upside here is there's no post-processing to be done when the -1 is entered, the result is ready to go.
You can use itertools.cycle to alternate between a remainder of 0 and 1, and use itertools.groupby to group odd-even sequences:
from itertools import groupby, cycle
l = [1,2,3,4,5,10,6,7,8,20,25,30,40]
r = cycle((0, 1))
print(max(sum(1 for i in g) for _, g in groupby(l, key=lambda n: n % 2 == next(r))))
This outputs: 6 (since the longest odd-even sequence is 1,2,3,4,5,10)
This is how I did. I think this might be simpler than the above examples.
def alternating(lst):
longSeries = []
currentSeries=[]
for i in range (len(lst)-1):
if i == 0:
currentSeries = [lst[0]]
if(abs(lst[i] - lst[i+1]) % 2 == 1):
currentSeries.append(lst[i+1])
else:
currentSeries = [lst[i+1]]
if(len(currentSeries) > len(longSeries)):
longSeries = currentSeries
print ("The longest series is: " +str(longSeries))
print(len(longSeries))
You can apply itertools.groupby twice:
import itertools
d = [[1,2,3,4,5,10,6,7,8,20,25,30,40,-1], [6,7,8,20,25,30,40,1,2,3,4,5,10,15,20,-1]]
def key_func(d):
start= not d[0]%2
for i in d[1:]:
if i%2 == start:
start = (not i%2)
else:
return False
return True
for l in d:
new_l = [list(b) for _, b in itertools.groupby(l, key=lambda x:x%2)]
second_l = [[i for [i] in b] for a, b in itertools.groupby(new_l, key=lambda x:len(x) ==1) if a]
print(max(second_l, key=lambda x:[key_func(x), len(x)]))
Output:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 10, 15, 20, -1]

Get the absolute difference between elements of a circular array

Let's say I have a array like l = [1, 3, 4, 5, 6, 8]
where the nth element represents the distance between the nth and n+1th object.
I want to find the distance between any two objects, and I used this code for this:
def dis(l_list, index1, index2, mylist):
m = mylist.index(index1)
n = mylist.index(index2)
i=0
j=0
if n > m:
while n >= m:
i = i + mylist[m]
m = m + 1
elif n < m:
while n <= m:
i = i + mylist[n]
n = n + 1
else:
return(0)
j = mylist[n] % l_mylist
print(abs(i - j))
l_mylist = input()
l_mylist = int(l_mylist)
mylist = []
mylist = list(map(int, input().split()))
i,j = input().split()
i, j=int(i), int(j)
dis(l_mylist, i, j, mylist)
but I am still getting the wrong output. Can anyone please point out where I am wrong?
If you want to sum around a potentially circular list. You can use a collections.deque() to rotate the list, e.g.:
from collections import deque
def dist(l, i1, i2):
d = deque(l)
d.rotate(-i1)
return sum(list(d)[:i2-i1]))
In []:
l = [1,2,3,4,5,6,7,8]
dist(l, 3-1, 6-1) # 3, 4, 5
Out[]:
12
In []:
dist(l, 6-1, 3-1) # 6, 7, 8, 1, 2
Out[]:
24
def distance(first_index, second_index, my_list):
temp_list = my_list + my_list
if (first_index > second_index):
first_index += len(my_list)
requested_sum = sum(my_list[second_index-1:first_index-1])
else:
requested_sum = sum(my_list[first_index-1:second_index-1])
return requested_sum
If I understood you correctly, then this should do the trick.
There are much more compact and efficient ways to do this, but this is the simplest and easiest to understand in my opinion.

Python given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A in O(n) time complexity

For example:
input: A = [ 6 4 3 -5 0 2 -7 1 ]
output: 5
Since 5 is the smallest positive integer that does not occur in the array.
I have written two solutions to that problem. The first one is good but I don't want to use any external libraries + its O(n)*log(n) complexity. The second solution "In which I need your help to optimize it" gives an error when the input is chaotic sequences length=10005 (with minus).
Solution 1:
from itertools import count, filterfalse
def minpositive(a):
return(next(filterfalse(set(a).__contains__, count(1))))
Solution 2:
def minpositive(a):
count = 0
b = list(set([i for i in a if i>0]))
if min(b, default = 0) > 1 or min(b, default = 0) == 0 :
min_val = 1
else:
min_val = min([b[i-1]+1 for i, x in enumerate(b) if x - b[i - 1] >1], default=b[-1]+1)
return min_val
Note: This was a demo test in codility, solution 1 got 100% and
solution 2 got 77 %.
Error in "solution2" was due to:
Performance tests ->
medium chaotic sequences length=10005 (with minus) got 3 expected
10000
Performance tests -> large chaotic + many -1, 1, 2, 3 (with
minus) got 5 expected 10000
Testing for the presence of a number in a set is fast in Python so you could try something like this:
def minpositive(a):
A = set(a)
ans = 1
while ans in A:
ans += 1
return ans
Fast for large arrays.
def minpositive(arr):
if 1 not in arr: # protection from error if ( max(arr) < 0 )
return 1
else:
maxArr = max(arr) # find max element in 'arr'
c1 = set(range(2, maxArr+2)) # create array from 2 to max
c2 = c1 - set(arr) # find all positive elements outside the array
return min(c2)
I have an easy solution. No need to sort.
def solution(A):
s = set(A)
m = max(A) + 2
for N in range(1, m):
if N not in s:
return N
return 1
Note: It is 100% total score (Correctness & Performance)
def minpositive(A):
"""Given an list A of N integers,
returns the smallest positive integer (greater than 0)
that does not occur in A in O(n) time complexity
Args:
A: list of integers
Returns:
integer: smallest positive integer
e.g:
A = [1,2,3]
smallest_positive_int = 4
"""
len_nrs_list = len(A)
N = set(range(1, len_nrs_list+2))
return min(N-set(A)) #gets the min value using the N integers
This solution passes the performance test with a score of 100%
def solution(A):
n = sorted(i for i in set(A) if i > 0) # Remove duplicates and negative numbers
if not n:
return 1
ln = len(n)
for i in range(1, ln + 1):
if i != n[i - 1]:
return i
return ln + 1
def solution(A):
B = set(sorted(A))
m = 1
for x in B:
if x == m:
m+=1
return m
Continuing on from Niroj Shrestha and najeeb-jebreel, added an initial portion to avoid iteration in case of a complete set. Especially important if the array is very large.
def smallest_positive_int(A):
sorted_A = sorted(A)
last_in_sorted_A = sorted_A[-1]
#check if straight continuous list
if len(sorted_A) == last_in_sorted_A:
return last_in_sorted_A + 1
else:
#incomplete list, iterate to find the smallest missing number
sol=1
for x in sorted_A:
if x == sol:
sol += 1
else:
break
return sol
A = [1,2,7,4,5,6]
print(smallest_positive_int(A))
This question doesn't really need another answer, but there is a solution that has not been proposed yet, that I believe to be faster than what's been presented so far.
As others have pointed out, we know the answer lies in the range [1, len(A)+1], inclusively. We can turn that into a set and take the minimum element in the set difference with A. That's a good O(N) solution since set operations are O(1).
However, we don't need to use a Python set to store [1, len(A)+1], because we're starting with a dense set. We can use an array instead, which will replace set hashing by list indexing and give us another O(N) solution with a lower constant.
def minpositive(a):
# the "set" of possible answer - values_found[i-1] will tell us whether i is in a
values_found = [False] * (len(a)+1)
# note any values in a in the range [1, len(a)+1] as found
for i in a:
if i > 0 and i <= len(a)+1:
values_found[i-1] = True
# extract the smallest value not found
for i, found in enumerate(values_found):
if not found:
return i+1
We know the final for loop always finds a value that was not marked, because it has one more element than a, so at least one of its cells was not set to True.
def check_min(a):
x= max(a)
if x-1 in a:
return x+1
elif x <= 0:
return 1
else:
return x-1
Correct me if i'm wrong but this works for me.
def solution(A):
clone = 1
A.sort()
for itr in range(max(A) + 2):
if itr not in A and itr >= 1:
clone = itr
break
return clone
print(solution([2,1,4,7]))
#returns 3
def solution(A):
n = 1
for i in A:
if n in A:
n = n+1
else:
return n
return n
def not_in_A(a):
a=sorted(a)
if max(a)<1:
return(1)
for i in range(0,len(a)-1):
if a[i+1]-a[i]>1:
out=a[i]+1
if out==0 or out<1:
continue
return(out)
return(max(a)+1)
mark and then find the first one that didn't find
nums = [ 6, 4, 3, -5, 0, 2, -7, 1 ]
def check_min(nums):
marks = [-1] * len(nums)
for idx, num in enumerate(nums):
if num >= 0:
marks[num] = idx
for idx, mark in enumerate(marks):
if mark == -1:
return idx
return idx + 1
I just modified the answer by #najeeb-jebreel and now the function gives an optimal solution.
def solution(A):
sorted_set = set(sorted(A))
sol = 1
for x in sorted_set:
if x == sol:
sol += 1
else:
break
return sol
I reduced the length of set before comparing
a=[1,222,3,4,24,5,6,7,8,9,10,15,2,3,3,11,-1]
#a=[1,2,3,6,3]
def sol(a_array):
a_set=set()
b_set=set()
cnt=1
for i in a_array:
#In order to get the greater performance
#Checking if element is greater than length+1
#then it can't be output( our result in solution)
if i<=len(a) and i >=1:
a_set.add(i) # Adding array element in set
b_set.add(cnt) # Adding iterator in set
cnt=cnt+1
b_set=b_set.difference(a_set)
if((len(b_set)) > 1):
return(min(b_set))
else:
return max(a_set)+1
sol(a)
def solution(A):
nw_A = sorted(set(A))
if all(i < 0 for i in nw_A):
return 1
else:
ans = 1
while ans in nw_A:
ans += 1
if ans not in nw_A:
return ans
For better performance if there is a possibility to import numpy package.
def solution(A):
import numpy as np
nw_A = np.unique(np.array(A))
if np.all((nw_A < 0)):
return 1
else:
ans = 1
while ans in nw_A:
ans += 1
if ans not in nw_A:
return ans
def solution(A):
# write your code in Python 3.6
min_num = float("inf")
set_A = set(A)
# finding the smallest number
for num in set_A:
if num < min_num:
min_num = num
# print(min_num)
#if negative make positive
if min_num < 0 or min_num == 0:
min_num = 1
# print(min_num)
# if in set add 1 until not
while min_num in set_A:
min_num += 1
return min_num
Not sure why this is not 100% in correctness. It is 100% performance
def solution(A):
arr = set(A)
N = set(range(1, 100001))
while N in arr:
N += 1
return min(N - arr)
solution([1, 2, 6, 4])
#returns 3

Categories

Resources