So I have to find the second largest number from list. I am doing it through simple loops.
My approach is to divide a list into two parts and then find the largest n
If you want an approach that consist in dividing the list, the nearest thing I can think in, is a MergeSort, it works dividing the list in 2, but it sorts a list. Then you can take the last 2 elements.
alist = [1, 7, 3, 2, 8, 5, 6, 4]
def find_2_largest(alist):
sorted_list = mergesort(alist)
return (sorted_list[-2], sorted_list[-1])
def merge(left, right):
result = []
i, j = 0, 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
def mergesort(alist):
if len(alist) < 2:
return alist
middle = len(alist) / 2
left = mergesort(alist[:middle])
right = mergesort(alist[middle:])
return merge(left, right)
print find_2_largest(alist)
biggest = None
second_biggest = None
biggest = num_list[0]
if num_list[1] > biggest:
second_biggest = num_list[1]
else:
second_biggest = biggest
biggest = num_list [1]
for n in num_list [2:]:
if n >= biggest:
biggest, second_biggest = n, biggest
elif n >= second_biggest:
second_biggest = n
print second_biggest
You don't have to sort the input, and this solution runs in O(n). Since your question says you cannot use builtin functions, you can use this
alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
largest, larger = alist[0], alist[0]
for num in alist:
if num > largest:
largest, larger = num, largest
elif num > larger:
larger = num
print larger
Output
100
Keep track of the largest number and the second largest number (larger
variable stores that in the code). If the current number is greater than the largest
, current number becomes the largest
, largest
becomes just larger
.
largest, larger = num, largest
is a shortcut for
temp = largest
largest = num
larger = temp
Edit: As per OP's request in the comments,
def findLarge(myList):
largest, larger = myList[0], myList[0]
for num in myList:
if num > largest:
largest, larger = num, largest
elif num > larger:
larger = num
return largest, larger
alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
firstLargest, firstLarger = findLarge(alist[:len(alist)//2])
secondLargest, secondLarger = findLarge(alist[len(alist)//2:])
print sorted((firstLarger, firstLargest, secondLarger, secondLargest))[-2]
O(n^2) algorithm:
In [79]: alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
In [80]: max(n for n in alist if n!=max(alist))
Out[80]: 100
O(n) algorithm:
In [81]: alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
In [82]: M = max(alist)
In [83]: max(n for n in alist if n!=M)
Out[83]: 100
Second largest number in the list:
alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
second_highest_number = sorted(list(set(alist)))[-2]
If you only want the 2nd largest element in the list (in cases where the highest value may occur twice), just skip the set() and list() call.
alist=[-45,0,3,10,90,5,-2,4,18,45,100,1,-266,706]
second_highest_number = sorted(alist)[-2]
I'm amazed that most answers (except by Christian) didn't try to answer OP's real question of finding the solution using divide-and-conquer approach.
This question is almost identical to this question: Finding the second smallest number from the given list using divide-and-conquer, but it tries to find the least instead of the largest.
For which this is my answer:
def two_min(arr):
n = len(arr)
if n==2:
if arr[0]<arr[1]: # Line 1
return (arr[0], arr[1])
else:
return (arr[1], arr[0])
(least_left, sec_least_left) = two_min(arr[0:n/2]) # Take the two minimum from the first half
(least_right, sec_least_right) = two_min(arr[n/2:]) # Take the two minimum from the second half
if least_left < least_right: # Line 2
least = least_left
if least_right < sec_least_left: # Line 3
return (least, least_right)
else:
return (least, sec_least_left)
else:
least = least_right
if least_left < sec_least_right: # Line 4
return (least, least_left)
else:
return (least, sec_least_right)
You can try to understand the code and change it to take the two largest. Basically you divide the array into two parts, then return the two largest numbers from the two parts. Then you compare the four numbers from the two parts, take the largest two, return.
This code has a bonus also for limiting the number of comparisons to 3n/2 - 2
.