Related
First, I want to find the highest number in the list which is the second number in the list, then split it in two parts. The first part contains the 2nd highest number, while the second part contains the number from the list that sums to the highest number. Then, return the list
eg: input: [4,9,6,3,2], expected output:[4,6,3,6,3,2] 6+3 sums to 9 which is the highest number in the list
Please code it without itertools.
python
def length(s):
val=max(s)
s.remove(val)
for j in s:
if j + j == val:
s.append(j)
s.append(j)
return s
Here's what I have but it doesn't return what the description states.
Any help would be appreciated as I spent DAYS on this.
Thanks,
The main issue in your code seems to be that you are editing the list s whilst iterating through it, which can cause issues with the compiler and is generally just something you want to avoid doing in programming. A solution to this could be iterating through a copy of the original list.
The second problem is that your program doesn't actually find the second biggest value in the list, just a value which doubles to give you the biggest value.
The final problem (which I unfortunately only noticed after uploading what I thought was a solution) is that the split values are appended to the end of the list rather than to the position where originally the largest value was.
Hopefully this helps:
def length(array):
val = max(array)
idx = array.index(val) # gets the position of the highest value in the array (val)
array.remove(val)
for i in array.copy(): # creates a copy of the original list which we can iterate through without causing buggy behaviour
if max(array) + i == val:
array = array[:idx] + [max(array), i] + array[idx:]
# Redefines the list by placing inside of it: all values in the list upto the previous highest values, the 2 values we got from splitting the highest value, and all values which previously went after the highest value.
return array
This will return None if there is no value which can be added to the second highest value to get the highest value in the given array.
Input:
print(length([1,2,3,4,5]))
print(length([4,8,4,3,2]))
print(length([11,17,3,2,20]))
print(length([11,17,3,2,21]))
Output:
[1, 2, 3, 4, 4, 1]
[4, 4, 4, 4, 3, 2]
[11, 17, 3, 2, 17, 3]
None
Here are the docs on list slicing (which are impossible to understand) and a handy tutorial.
when you say "The first part contains the 2nd highest number" does that mean second highest number from the list or the larger of the two numbers that add up the largest number from list?
Here I assume you just wanted the larger of the two numbers that add up to the largest number to come first.
def length(s:list):
#start by finding the largest value and it's position in the list:
largest_pos = 0
for i in range(len(s)):
if s[i] > s[largest_pos]:
largest_pos = i
# find two numbers that add up to the largest number in the s
for trail in range(len(s)):
for lead in range(trail, len(s)):
if (s[trail] + s[lead]) == s[largest_pos]:
if s[trail] > s[lead]:
s[largest_pos] = s[trail]
s.insert(largest_pos +1, s[lead])
else:
s[largest_pos] = s[lead]
s.insert(largest_pos + 1, s[trail])
return s
# if no two numbers add up to the largest number. return s
return s
Since you are limited to 2 numbers, a simple nested loop works.
def length(s):
val = max(s)
idx = s.index(val)
s.remove(val)
for i in range(len(s) - 1):
for j in range(i + 1, len(s)):
if s[i] + s[j] == val:
s = s[:idx] + [s[i], s[j]] + s[idx:]
return s
print(length([4,9,6,3,2]))
Output:
[4, 6, 3, 6, 3, 2]
I used deque library
first to find the highest element or elements then remove all of them and replace them with second high value and rest like : 9 replace with 6 and 3 in example:
from collections import deque
l = [4, 9, 6, 3, 2]
a = deque(l)
e = a.copy()
s = max(a)
while s in a:
a.remove(s) # remove all highest elements
s2 = max(a) # find second high value
c = s - s2
for i in l:
if i == s:
w = e.index(i) # find index of high values
e.remove(max(e))
e.insert(w, s2)
e.insert(w+1, c)
print(list(e))
I'm trying to solve the problem which is defined as:
we are given two integer arrays nums1 and nums2, sorted in non-decreasing order, and two integers m and n, representing the number of elements in nums1 and nums2 respectively.
Merge nums1 and nums2 into a single array sorted in non-decreasing order.
The function should not return the final sorted array, but instead, be stored inside the array nums1. To accommodate this, nums1 has a length of m + n, where the first m elements denote the elements that should be merged, and the last n elements are set to 0 and should be ignored. nums2 has a length of n.
I have written the following code in python :
def merge(nums1, m, nums2, n):
"""
Do not return anything, modify nums1 in-place instead.
"""
nums1=nums1[:m]
# print("before",nums1)
for i in nums1[m:n]:
i=0
# print("after1",nums1)
nums1[m:n]=nums2[:n]
nums1.sort()
# print(nums1)
merge([0],0,[1],1)
I have tried to submit the solution but showing up as an error. Can anyone find the solution to the given problem? Please do something with the above code, not anything from outside.
Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Explanation: The arrays we are merging are [1,2,3] and [2,5,6].
The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1.
You would like us to start from your code attempt, but none of the statements in your attempt are salvageable in an efficient solution:
nums1=nums1[:m]. This statement creates a new list, storing its reference in the variable that had a reference to the original input list. Thereby you lose the reference to the input list, and make it impossible to change anything in that list -- which was the purpose of this function.
for i in nums1[m:n]: In an efficient solution, you would not create a new list (like with using slice notation).
i=0: there is no benefit in repeating this in a loop. This is an assignment to a variable, not to a member of a list. It seems you thought this loop would clear part of the original list, but you cannot clear a list by assigning 0 to a variable. Moreover, there is no need to clear anything in any list for this code challenge.
nums1[m:n]=nums2[:n] although this copies the second list into nums1, this is copying it in a local list -- a list that the caller has no access to. Secondly, you would need to use the free space in the left list to efficiently merge the data. Now by having copied all values from the second list in it, you don't have any space anymore for such merge.
nums1.sort(). Calling sort defeats the purpose of the code challenge. sort doesn't use the knowledge that we're dealing with 2 sorted lists, and can only offer a time complexity of O(nlogn), while you can do it with a complexity of O(n).
So... nothing in your code can stay. It goes wrong from the first statement onwards, and takes the wrong approach.
The algorithm that should be implemented will have an index going from end to start in the nums1 and store the greatest value there from the values that have not yet been stored that way. As the input lists are sorted, there are only 2 values candidate for this operation.
Here is an implementation:
def merge(nums1, m, nums2, n):
# Let m and n refer to the last used index in given lists
m -= 1
n -= 1
for i in range(m + n + 1, -1, -1):
if n < 0 or m >= 0 and nums1[m] > nums2[n]:
nums1[i] = nums1[m]
m -= 1
else:
nums1[i] = nums2[n]
n -= 1
What you are asking for is just the classic function used within the merge sort algorithm. You can find many solutions online.
Here is a possible solution:
def merge(nums1, m, nums2, n):
i = m - 1
j = n - 1
for last in range(m + n - 1, -1, -1):
if i < 0:
nums1[last] = nums2[j]
j -= 1
elif j < 0:
nums1[last] = nums1[i]
i -= 1
elif nums1[i] < nums2[j]:
nums1[last] = nums2[j]
j -= 1
else:
nums1[last] = nums1[i]
i -= 1
Example:
>>> nums1 = [1, 3, 5, 7, 0, 0, 0]
>>> nums2 = [4, 6, 8]
>>> m = 4
>>> n = 3
>>> merge(nums1, m, nums2, n)
>>> nums1
[1, 3, 4, 5, 6, 7, 8]
Another example:
>>> nums1 = [1, 2, 3, 0, 0, 0]
>>> nums2 = [2, 5, 6]
>>> m = 3
>>> n = 3
>>> merge(nums1, m, nums2, n)
>>> nums1
[1, 2, 2, 3, 5, 6]
If you want to keep your original code and fix it then you can do this:
def merge(nums1, m, nums2, n):
nums1[m:] = nums2
nums1.sort()
Beware that this is much slower than my solution, and it's not the standard way to solve this well known problem.
This is a Find All Numbers Disappeared in an Array problem from LeetCode:
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array),
some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may
assume the returned list does not count as extra space.
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]
My code is below - I think its O(N) but interviewer disagrees
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
results_list=[]
for i in range(1,len(nums)+1):
if i not in nums:
results_list.append(i)
return results_list
You can implement an algorithm where you loop through each element of the list and set each element at index i to a negative integer if the list contains the element i as one of the values,. You can then add each index i which is positive to your list of missing items. It doesn't take any additional space and uses at the most 3 for loops(not nested), which makes the complexity O(3*n), which is basically O(n). This site explains it much better and also provides the source code.
edit- I have added the code in case someone wants it:
#The input list and the output list
input = [4, 5, 3, 3, 1, 7, 10, 4, 5, 3]
missing_elements = []
#Loop through each element i and set input[i - 1] to -input[i - 1]. abs() is necessary for
#this or it shows an error
for i in input:
if(input[abs(i) - 1] > 0):
input[abs(i) - 1] = -input[abs(i) - 1]
#Loop through the list again and append each positive value to output list
for i in range(0, len(input)):
if input[i] > 0:
missing_elements.append(i + 1)
For me using loops is not the best way to do it because loops increase the complexity of the given problem. You can try doing it with sets.
def findMissingNums(input_arr):
max_num = max(input_arr) # get max number from input list/array
input_set = set(input_arr) # convert input array into a set
set_num = set(range(1,max(input_arr)+1)) #create a set of all num from 1 to n (n is the max from the input array)
missing_nums = list(set_num - input_set) # take difference of both sets and convert to list/array
return missing_nums
input_arr = [4,3,2,7,8,2,3,1] # 1 <= input_arr[i] <= n
print(findMissingNums(input_arr)) # outputs [5 , 6]```
Use hash table, or dictionary in Python:
def findDisappearedNumbers(self, nums):
hash_table={}
for i in range(1,len(nums)+1):
hash_table[i] = False
for num in nums:
hash_table[num] = True
for i in range(1,len(nums)+1):
if not hash_table[i]:
print("missing..",i)
Try the following :
a=input() #[4,3,2,7,8,2,3,1]
b=[x for x in range(1,len(a)+1)]
c,d=set(a),set(b)
print(list(d-c))
The Padovan sequence is governed by the relationship P(n+1) = P(n-1) + P(n-2), for n is a
non-negative integer, where P(0) = P(1) = P(2) = 1. So, for instance, P(3) = 2, P(4) = 2, and
P (5) = 3, and so on.
I want to write a Python program Pad(n) that generates the sequence P(0), P(1), ..., P(n - 1).
This is what I have this far, but it only produces a list with the ith number replicated up to the largest number in the sequence:
def ith(n):
first, sec, third, fourth = 1, 1, 1, 1
for i in range(3, n+1):
fourth = first + sec
first = sec
sec = third
third = fourth
return fourth
def pad(n):
pad = ith(n)
lst = []
for i in range(n):
lst.append(pad)
return lst
I want it to produce this as an output:
>>> Pad(6)
>>>[1,1,1,2,2,3]
Currently my code only produces:
>>>[4,4,4,4,4,4]
I now that I append the ith value ith number of times to the list, but I dont know how to append each number in series up to and including the value for the last number. Pad(6) yields 4 since this is all the previous relationships put together.
Sorry for my bad description and formulating of the problem.
You have a two minor errors in your pad() function.
First you should be calling the ith() function inside the loop (also don't name the variable pad as that's the name of the function and it can cause problems).
Secondly, you are calling ith(n) inside the loop when you should be calling ith(i). This is the reason that you were always getting the same number- the argument to ith() was not changing inside the loop.
A fixed version of your pad() function would be:
def pad(n):
lst = []
for i in range(n):
val = ith(i)
lst.append(val)
return lst
You can verify that this indeed produces the correct output of [1, 1, 1, 2, 2, 3] for pad(6).
More efficient non-recursive method
Now, while your method works, it's also very inefficient. You are calling the ith() function for every value in range(n) which recomputes the entire sequence from the beginning each time.
A better way would be to store the intermediate results in a list, rather than by calling a function to get the ith() value.
Here is an example of a better way:
def pad2(n):
lst = [1, 1, 1] # initialize the list to the first three values in the sequence
for i in range(3,n):
lst.append(lst[i-2] + lst[i-3]) # use already computed values!
# slice the list to only return first n values (to handle case of n <= 3)
return lst[:n]
Recursive method
As seen on Wikipedia, the recurrence relation shows us that pad(n) = pad(n-2) + pad(n-3).
Use this as the starting point for a recursive function: return pad(n-2) + pad(n-3)
This is almost everything you need, except we have to define the starting values for the sequence. So just return 1 if n < 3, otherwise use the recurrence relation:
def pad_recursive(n):
if n < 3:
return 1
else:
return pad_recursive(n-2) + pad_recursive(n-3)
Then you can get the first n values in the sequence via list comprehension:
print([pad_recursive(n) for n in range(6)])
#[1, 1, 1, 2, 2, 3]
But this suffers from the same drawback as your original function as it computes the entire sequence from scratch in each iteration.
I have to figure out which is larger, the first or last element in a given list, and set all the other elements to be that value.
I wrote a code using a for loop, but I get an error that the list index is out of range. What is my mistake?
The code is below:
def max_end3(nums):
for i in nums:
if (nums[0] > nums[len(nums)-1]):
nums[i] = nums[0]
else:
nums[i] = nums[len(nums)-1]
return (nums)
Here is an option:
the_list = [6, 7, 2, 4, 5, 7]
val = max([the_list[0], the_list[-1])
the_list = [val]*len(the_list)
You've confused an index with a list element. Consider the input list [17, 3, -42, -3]. Your for statement steps i through the values 17, 3, -42, and -3, in that order. However, the assignments you do assume that i is taking on the position or index values, 0, 1, 2, 3.
Try this, instead:
def max_end3(nums):
for i in range(len(nums)):
if (nums[0] > nums[len(nums)-1]):
nums[i] = nums[0]
You do not have to do for loop since 'nums is already a list. I believe coding bat is giving array length is 3. So try this
def max_end3(nums):
if nums[0] > nums[-1]:
return nums[:1] *3
elif nums[-1] > nums[0]:
return nums[-1:] * 3
elif nums[0] == nums[-1]:
return nums[:1] * 3
else:
return nums
for i in nums / nums[i] is not the proper way to index the list nums. I think you can try this instead:
def max_end3(nums):
for i,num in enumerate(nums):
if (nums[0] > nums[-1]):
nums[i] = nums[0]
else:
nums[i] = nums[-1]
return (nums)
Use the built-in enumerate function to return "a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over sequence." This allows you to concurrently index & iterate the values.
Use nums[-1] to represent the last item in the list, since Python supports negative indexing :)
Note: other solutions are more elegant, and this is not how I would solve the problem, but for a beginner it is sometimes easier to understand if working with simple constructs like for loop.
To replace each element in the given list I would pre-compute the wanted value, and then assign it to each element, thus:
def max_end3(nums):
larger = max((nums[0], nums[-1]))
for i in range(len(nums)):
nums[i] = larger
You could alternatively leave the original list unchanged, and generate a new list of the wanted values. If the new list is assigned to the same name as the old one, it will have a similar effect, eg.
nums = [max((nums[0], nums[-1]))] * len(nums)