I wrote a python program to give all the permutations of a string, using backtracking:
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if nums == None or len(nums) <= 1:
return [nums]
res_lst = []
res = []
self.permuteHelper(res_lst, nums, res)
return res_lst
def permuteHelper(self, res_lst, nums, res):
if len(res) == len(nums):
res_lst.append(res)
return
for n in nums:
if n not in res:
self.permuteHelper(res_lst, nums,res+[n])
res = res[:-1] #Prune back one node
This one always exceeds the maximum recursion limit. Since at each recursion step I pass result list + [n] to the next recursion call, I suppose it will finally reach the end case len(res) == len(nums).
Doe anybody have idea why that does not happen?
Ah, that was subtle. Remove the line:
res = res[:-1] #Prune back one node
And it works. You remove one digit from the given permutation, which means that for each time you do that, you add one recursion level to the recursion, so you keep having to go deeper and deeper.
Also it messes up the permutations completely.
Here's an iterative implementation of permutations:
import itertools
def permutations(*args):
res = list(args)
if len(res) > 0:
for n in itertools.count():
yield tuple(res)
i = x = 2
while n % x == x - 1:
i += 1
x *= i
if i > len(res):
break
j = (n + 1) % x * i // x
res[-i], res[-j] = res[-j], res[-i]
res[1 - i:] = res[:-i:-1]
Note that this doesn't have any special handling for duplicate values.
Related
This Python code is not working for some test cases on code wars two sum. Here is the link to the problem:
https://www.codewars.com/kata/52c31f8e6605bcc646000082/train/python
def two_sum(nums, target):
nums.sort()
l = 0
r = len(nums)-1
while l < r:
sum = nums[l] + nums[r]
if sum == target:
return [l, r]
if sum > target:
r -= 1
if sum < target:
l += 1
return []
Any help is much appreciated! :)
The solution you are looking for will be:
def two_sum(nums, target):
indices = {}
for index, num in enumerate(nums):
remainder = target - num
if remainder in indices:
return indices[remainder], index
indices[num] = index
return 0, 0
Right off the bat, I can also tell you that sorting nums before doing anything else is bad because the original indices can get mixed up.
def two_sum(numbers, target):
for n1 in enumerate(numbers):
for n2 in enumerate(numbers):
if n1[0] != n2[0]:
if (n1[1] + n2[1]) == target:
return [n1[0], n2[0]]
I decided to complete some tasks on Leetcode to improve my algorithm skills.
And I ran into a problem with LeetCode's problem 985. Sum of Even Numbers After Queries
Here is the description of that task:
You are given an integer array nums and an array queries where queries[i] = [valᵢ, indexᵢ].
For each query i, first, apply nums[indexᵢ] = nums[indexᵢ] + valᵢ, then print the sum of the even values of nums.
Return an integer array answer where answer[i] is the answer to the ith query.
Some samples of input and output:
# input1: nums = [1,2,3,4], queries = [[1,0],[-3,1],[-4,0],[2,3]]
# output1: [8, 6, 2, 4]
# input2: nums = [1], queries = [[4,0]]
# output2: [0]
So I found the solution, but as it has some huge samples of inputs, I found that my code is not efficient enough.
Here is my code:
class Solution:
def sumEvenAfterQueries(self, nums: list[int], queries: list[list[int]]) -> list[int]:
ans = []
integer_ans = 0
for i in range(len(queries)):
nums[queries[i][1]] = nums[queries[i][1]] + queries[i][0]
for j in nums:
if j % 2 == 0:
integer_ans += j
ans.append(integer_ans)
integer_ans = 0
return ans
So it does not solve problem because of the Time limit exceeded.
How can I improve my code to make it more efficient?
Try this solution. This will initially build up even_nums which are sum of even numbers in list, then incrementally update it with each value in queries.
It's probably not the most efficient, but it works for me. I submit on leetcode just now.
class Solution:
def sumEvenAfterQueries(self, nums: List[int], queries: List[List[int]]) -> List[int]:
even_sum = sum(x for x in nums if not x % 2)
result = []
for (add, i) in queries:
n = nums[i]
if add % 2: # odd
if n % 2: # both odd, result is even
even_sum += n + add
else: # even, add odd, result is odd
even_sum -= n
# odd, add even, result is still odd
# so, both must be even
elif not n % 2: # both even
even_sum += add
# remember updating nums at index #i
# and then adding to ours result
nums[i] = n + add
result.append(even_sum)
return result
Not so optimised solution, but you need to keep update of the sum of even values first and then for every query you run, you need to make the changes for the index of that value and see if sum for that index is calcualed or not. if not then add it to total sum and update the nums and if it is calculate then add the new sum value to it and modify the nums accordingly.
below is a simple way to achive this.
class Solution:
def sumEvenAfterQueries(self, nums: List[int], queries: List[List[int]]) -> List[int]:
dic = {i:v for i, v in enumerate(nums) if v%2==0}
sum_ = sum(dic.values())
res = []
for v, i in queries:
val = nums[i]
new_val = nums[i] + v
if i not in dic:
if new_val%2==0:
dic[i] = new_val
sum_ += new_val
res.append(sum_)
else:
res.append(sum_)
else:
if new_val%2==0:
sum_ -= val
sum_ += new_val
dic[i] = new_val
res.append(sum_)
else:
sum_-= val
del dic[i]
res.append(sum_)
nums[i] = new_val
return res
This is an addition to rv.kvetch answer
Your code is giving TLE because it has the worst case time complexity of O(n2). I hope you know about the it.
Coming to the solution, we can do in in O(n) i.e. linear time.
Algorithm
Initially we will store sum of all even numbers present in nums to all_sum
Adding value to any item of nums list can make nums[index] + value even or odd, we will check these conditions
Based on these conditions checks, we either add (value or nums[index] + value) or subtract nums[index] from all_sum
After all these condition checks we will modify nums[index] to be nums[index] = nums[index] + value and add all_sum to the array that we want to return as answer
Code
def sumEvenAfterQueries(self, nums: List[int], queries: List[List[int]]) -> List[int]:
all_sum = 0
for e in nums:
if e%2 == 0:
all_sum += e
sum_arr = []
for val, index in queries:
if nums[index] % 2 == 0: # nums item is already added to all_sum
if (nums[index] + val) % 2 == 0:
all_sum += val
else:
all_sum -= nums[index]
else: # nums item is odd so it wasn't added to all_sum before
if (nums[index] + val) % 2 == 0:
all_sum += (nums[index] + val)
else:
pass
nums[index] += val
sum_arr.append(all_sum)
return sum_arr
The question, https://leetcode.com/problems/first-missing-positive/, asks:
Given an unsorted integer array nums, return the smallest missing positive integer.
You must implement an algorithm that runs in O(n) time and uses constant extra space.
Example 1:
Input: nums = [1,2,0]
Output: 3
Example 2:
Input: nums = [3,4,-1,1]
Output: 2
Example 3:
Input: nums = [7,8,9,11,12]
Output: 1
Constraints:
1 <= nums.length <= 5 * 10**5
-2**31 <= nums[i] <= 2**31 - 1
Thus my code satisfies this:
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
nums=sorted(list(filter(lambda x: x>=0, nums)))
nums= list(dict.fromkeys(nums))
if 1 not in nums: return 1
x=nums[0]
for num in nums:
if nums.index(num) != 0:
dif = num - x
if dif!=1:
return x + 1
x=num
return num+1
Glad for anyone to offer help.
As the comments described, sorted() doesn't take linear time. sorted() also creates a new list, so your solution also violates the O(1) memory constraint.
Here's a linear-time, constant-space solution. The problem asks for two things (for simplicity, let n = len(nums)):
a data structure that can in O(1) time, determine whether a positive integer in the interval [1, n] is in nums. (We have n numbers to check, and the runtime of our algorithm has to be linear.) For this problem, our strategy is to create a table such that for every integer i between 1 and n, if i is in nums, then nums[i - 1] = i. (The answer has to be positive, and the answer can't be greater than n + 1 -- the only way for the answer to be n + 1 is if nums contains every integer in the interval [1, n]).
a procedure to generate the data structure in-place to meet the memory constraint.
Here's a solution that does this.
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
# Match elements to their indicies.
for index, num in enumerate(nums):
num_to_place = num
while num_to_place > 0 and num_to_place <= len(nums) and num_to_place != nums[num_to_place - 1]:
next_num_to_place = nums[num_to_place - 1]
nums[num_to_place - 1] = num_to_place
num_to_place = next_num_to_place
# Find smallest number that doesn't exist in the array.
for i in range(len(nums)):
if nums[i] != i + 1:
return i + 1
return len(nums) + 1
Both for loops takes linear time. The reasoning for the second is obvious, but the time analysis of the first is a bit more subtle:
Notice that the while loop contains this condition: num_to_place != nums[num_to_place - 1]. For each iteration of this while loop, the number of values that meet this condition decreases by 1. So, this while loop can only execute at most n times across all iterations, meaning the first for loop takes O(n) time.
# O(n) time and O(1) space
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
index = 0
while index < len(nums):
if nums[index] > 0 and nums[index] - 1 < len(nums) and nums[index] != nums[nums[index] - 1]:
nums[nums[index]-1], nums[index] = nums[index], nums[nums[index] - 1]
else:
index += 1
for i, integer in enumerate(nums):
if integer != i + 1:
return i + 1
return len(nums) + 1
I want to find a sum with pair of numbers in python list.
List is sorted
Need to check consecutive combinations
Avoid using for loop
I used a for loop to get the job done and its working fine. I want to learn other optimized way to get the same result.
Can I get the same result with other ways without using a for loop?
How could I use binary search in this situation?
This is my code:
def query_sum(list, find_sum):
"""
This function will find sum of two pairs in list
and return True if sum exist in list
:param list:
:param find_sum:
:return:
"""
previous = 0
for number in list:
sum_value = previous + number
if sum_value == find_sum:
print("Yes sum exist with pair {} {}".format(previous, number))
return True
previous = number
x = [1, 2, 3, 4, 5]
y = [1, 2, 4, 8, 16]
query_sum(x, 7)
query_sum(y, 3)
this is the result.
Yes sum exist with pair 3 4
Yes sum exist with pair 1 2
You can indeed use binary search if your list is sorted (and you are only looking at sums of successive elements), since the sums will be monotonically increasing as well. In a list of N elements, there are N-1 successive pairs. You can copy and paste any properly implemented binary search algorithm you find online and replace the criteria with the sum of successive elements. For example:
def query_sum(seq, target):
def bsearch(l, r):
if r >= l:
mid = l + (r - l) // 2
s = sum(seq[mid:mid + 2])
if s == target:
return mid
elif s > target:
return bsearch(l, mid - 1)
else:
return bsearch(mid + 1, r)
else:
return -1
i = bsearch(0, len(seq) - 1)
if i < 0:
return False
print("Sum {} exists with pair {} {}".format(target, *seq[i:i + 2]))
return True
IDEOne Link
You could use the built-in bisect module, but then you would have to pre-compute the sums. This is a much cheaper method since you only have to compute log2(N) sums.
Also, this solution avoids looping using recursion, but you might be better off writing a loop like while r >= l: around the logic instead of using recursion:
def query_sum(seq, target):
def bsearch(l, r):
while r >= l:
mid = l + (r - l) // 2
s = sum(seq[mid:mid + 2])
if s == target:
return mid
elif s > target:
r = mid - 1
else:
l = mid + 1
return -1
i = bsearch(0, len(seq) - 1)
if i < 0:
return False
print("Yes sum exist with pair {} {}".format(*seq[i:i + 2]))
return True
IDEOne Link
# simpler one:
def query_sum(seq, target):
def search(seq, index, target):
if index < len(seq):
if sum(seq[index:index+2]) == target:
return index
else:
return search(seq, index+1, target)
else:
return -1
return search(seq, 0, target)
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