Python Code Not Working!-- Convert array into Zig-Zag fashion - python-3.x

Given an array arr of distinct elements of size N, the task is to rearrange the elements of the array in a zig-zag fashion so that the converted array should be in the below form:
arr[0] < arr[1] > arr[2] < arr[3] > arr[4] < . . . . arr[n-2] < arr[n-1] > arr[n].
def zigZag(self,arr, n):
res=[]
r=(n//2)+1
arr.sort()
j=0
i=0
for k in range(0, r, 1):
res.insert(i, arr[j])
res.insert(i+1, arr[j+r])
i= i+2
j+= j
return res

You can sort the array and add to the new array from both sides of the array.
def zigZag(self, arr, n):
res=[None]*n
arr.sort()
i = 0
j = 0
while i < n//2:
res[j] = arr[i]
res[j+1] = arr[n-1-i]
i+=1
j+=2
if n%2 == 1:
res[-1] = arr[n//2]
return res

Related

658. Find K Closest Elements - for loop 'comp' comparison variable not updating as expected

So I am working on problem 658 'Find K Closest Elements'(https://leetcode.com/problems/find-k-closest-elements/), which asks to return a list from the given list, 'arr'. This return list will be the length of 'k' and will contain the 'k' # of values closest to the given 'x' value. I've created all the base cases and constraints, and am now stuck on the comparison part below:
I've created an empty list, 'a'. While the length of 'a' is not 'k', the function will go through the list and compare abs(i - x) < abs(comp - x), 'comp' starting at 'arr[0]' and updating to 'i' if the comparison is true. The problem is that the comparison is not working correctly. Here is an example case I'm trying to figure out:
arr = [1,1,1,10,10,10], k = 4, x = 9
Below is the portion of the code I am focusing on:
a = []
comp = arr[0]
iteration = 0
i_index = 0
while len(a) != k:
for i in arr:
comp_1 = abs(i - x)
comp_2 = abs(comp - x)
if comp_1 < comp_2:
comp == i
print(f"comp: {comp}")
arr.pop(arr.index(comp))
a.append(comp)
return a
I am including the entirety of the code just in case below:
def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]:
# Constraints
if k < 1 or k > len(arr):
return "k must be greater than 0 and less than the arr length"
if len(arr) < 1 or len(arr) > 10**4:
return "arr length must be greater than 0 and less than 10^4"
if x > 10**4:
return "x must be less than 10^4"
if sorted(arr) != arr:
return "arr must be sorted"
for i in arr:
if i < -10**4:
return "arr item cannot be less than -10^4"
#Variables 1
begin = arr[:k]
end = arr[-k:]
# Base cases
if len(arr) == k:
return arr
if x < arr[0]:
return begin
elif x > arr[-1]:
return end
try:
x_index = arr.index(x)
half_k = int(k/2)
#if k == x and x_index != None:
# return [x]
# Captures all other lists that begin at arr[0] or end at arr[-1]
if x_index - half_k < 0:
return begin
elif x_index + half_k > len(arr) - 1:
return end
# Create list out of interior of arr if necessary
else:
return arr[x_index - half_k : x_index + half_k]
# Means x is not in arr
except ValueError:
a = []
comp = arr[0]
iteration = 0
i_index = 0
while len(a) != k:
for i in arr:
print(f"{iteration} - {i_index}:")
print(f"i: {i}")
print(f"comp_1: {abs(i - x)}")
print(f"comp_2: {abs(comp - x)}")
comp_1 = abs(i - x)
comp_2 = abs(comp - x)
if comp_1 < comp_2:
comp == i
print(f"comp: {comp}")
i_index += 1
print("\n")
iteration += 1
arr.pop(arr.index(comp))
a.append(comp)
return a
I would take the approach of:
finding the shortest distance from x to the elements of arr.
sorting arr by the distances.
So, this is a good method:
arr = [1,1,1,10,10,10]
k = 4
x = 9
distances = [abs(x - n) for n in arr]
Z = [a for _,a in sorted(zip(distances,arr))]
print(Z[:k])
result
[10, 10, 10, 1]

how to count how many element changed its position in a list after sorting?

I want to print the count of numbers that have changed their position.
My code:
def mysort(arr):
count = 0
for i in range(len(arr)):
min_value = i
for j in range(i, len(arr)):
if arr[j] < arr[min_value]:
min_value = j
count += 1
temp = arr[i]
arr[i] = arr[min_value]
arr[min_value] = temp
return count
my_list = [4,2,3,1,6,5]
print(mysort(my_list))
My code is returning 3 as output but it should return 4. How can I fix it?
To count the number of elements with positions changed, why not try:
def count_change(old, new):
# assume old and new have the same length
count = 0
for x,y in zip(old, new):
if x != y:
count += 1
return count
Your code actually counts the number of value swap

updating value of argument passed in function

I am trying merge sort but the values in the list is not updating . I know arguments are passed by assignments .but how this code is not working
def mergeSort(arr):
#add code here
if len(arr) <2 :
return
mid = len(arr)//2
s1 = arr[:mid]
s2 = arr[mid:]
mergeSort(s1)
mergeSort(s2)
i= 0 ; j =0
while i+j < len(arr):
if i<len(s1) or j ==len(s2) and s1[i] <s2[j] :
arr[i+j] = s1[i]
i +=1
else :
arr[i+j] = s2[j]
j +=1
return arr
mergeSort(arr)
for ex arr =[5,4,3,2,1]
the output is same arr,
but this code is working fine
def mergeSort(arr):
#add code here
if len(arr)>1:
mid=len(arr)//2
l=arr[:mid]
r=arr[mid:]
mergeSort(l)
mergeSort(r)
i=j=k=0
while i<len(l) and j<len(r):
if l[i]<r[j]:
arr[k]=l[i]
i+=1
else:
arr[k]=r[j]
j+=1
k+=1
while i<len(l):
arr[k]=l[i]
i+=1
k+=1
while j<len(r):
arr[k]=r[j]
j+=1
k+=1
return arr
mergeSort(arr)
I don't know what i'm missing ? How the one is updating outer array and one not.

Troubleshooting creating a function to swap elements in Python 3

I am having trouble understanding the for loop needed to create a function that swaps elements in a Python list.
I am trying to create the function using one for loop but apparently more than one is required
Inputs:
n = int(input().strip())
a = list(map(int, input().strip().split(' ')))
My method:
def count_swaps(a):
total_swaps = 0
i = 0
if a[i + 1] > a[i]:
total_swaps += 1
temp = a[i+1]
a[i+1] = a[i]
a[i] = temp
return total_swaps
Correct solution:
def count_swaps(a):
total_swaps = 0
for i in range(n):
swaps = 0
for j in range(n-1):
if a[j] > a[j+1]:
temp = a[j+1]
a[j+1] = a[j]
a[j] = temp
swaps += 1
total_swaps += swaps
return total_swaps
My question is, why is there need of two for loops, i.e. the j in range(n-1) and i in range(n)? In addition, should the range not be the same in both?

Buggy merge sort implementation

My merge sort implementation is buggy since i am not getting two sorted list before calling merge.I am not sure what is wrong with it.
def mergeSort(arr):
if len(arr) == 1 : return arr
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
mergeSort(left_half)
mergeSort(right_half)
return merge(left_half,right_half)
def merge(list1,list2):
res = []
i = 0
j = 0
while i < len(list1) and j < len(list2):
if list1[i] < list2[j]:
res.append(list1[i])
i += 1
elif list1[i] > list2[j]:
res.append(list2[j])
j += 1
#Add remaining to res if any
while i < len(list1):
res.append(list1[i])
i += 1
while j < len(list2):
res.append(list2[j])
j += 1
return res
A = [5,1,2,15]
print(mergeSort(A))
My understanding of merge sort is that the space complexity is O(n) since n items in memory (in the final merge).Is quick sort preferred over merge sort just because quick sort is in-place?
I not python expert, but you should write
left_half = arr[:mid]
right_half = arr[mid:]
left_half = mergeSort(left_half)
right_half = mergeSort(right_half)
Because your mergeSort return copy of sorted array.
You have 3 mistakes in your code.
The first is that you don't handle the empty list. You need a <= instead of an == in your second line.
The second is that by simply calling mergeSort(left_half) you suppose that it will sort left_half “by reference”, which it doesn't (same with right_half).
The third is that you aren't doing anything in the case list1[i] == list2[j]. Actually you don't need that elif, you simply need an else. It doesn't matter whether you append list1[i] or list2[j] if they are equal, but you must append one of the two.
Your code should rather be:
def mergeSort(arr):
if len(arr) <= 1 : return arr
mid = len(arr) // 2
left_half = mergeSort(arr[:mid])
right_half = mergeSort(arr[mid:])
return merge(left_half, right_half)
def merge(list1, list2):
res = []
i = 0
j = 0
while i < len(list1) and j < len(list2):
if list1[i] < list2[j]:
res.append(list1[i])
i += 1
else:
res.append(list2[j])
j += 1
#Add remaining to res if any
...
As for your questions about space complexity and comparison with quicksort, there are already answers here on StackOverflow (here and here).

Resources