Binary TreesBinary Trees36

  1. 1Preorder Traversal of a Binary Tree using Recursion
  2. 2Preorder Traversal of a Binary Tree using Iteration
  3. 3Postorder Traversal of a Binary Tree Using Recursion
  4. 4Postorder Traversal of a Binary Tree using Iteration
  5. 5Level Order Traversal of a Binary Tree using Recursion
  6. 6Level Order Traversal of a Binary Tree using Iteration
  7. 7Reverse Level Order Traversal of a Binary Tree using Iteration
  8. 8Reverse Level Order Traversal of a Binary Tree using Recursion
  9. 9Find Height of a Binary Tree
  10. 10Find Diameter of a Binary Tree
  11. 11Find Mirror of a Binary Tree - Todo
  12. 12Inorder Traversal of a Binary Tree using Recursion
  13. 13Inorder Traversal of a Binary Tree using Iteration
  14. 14Left View of a Binary Tree
  15. 15Right View of a Binary Tree
  16. 16Top View of a Binary Tree
  17. 17Bottom View of a Binary Tree
  18. 18Zigzag Traversal of a Binary Tree
  19. 19Check if a Binary Tree is Balanced
  20. 20Diagonal Traversal of a Binary Tree
  21. 21Boundary Traversal of a Binary Tree
  22. 22Construct a Binary Tree from a String with Bracket Representation
  23. 23Convert a Binary Tree into a Doubly Linked List
  24. 24Convert a Binary Tree into a Sum Tree
  25. 25Find Minimum Swaps Required to Convert a Binary Tree into a BST
  26. 26Check if a Binary Tree is a Sum Tree
  27. 27Check if All Leaf Nodes are at the Same Level in a Binary Tree
  28. 28Lowest Common Ancestor (LCA) in a Binary Tree
  29. 29Solve the Tree Isomorphism Problem
  30. 30Check if a Binary Tree Contains Duplicate Subtrees of Size 2 or More
  31. 31Check if Two Binary Trees are Mirror Images
  32. 32Calculate the Sum of Nodes on the Longest Path from Root to Leaf in a Binary Tree
  33. 33Print All Paths in a Binary Tree with a Given Sum
  34. 34Find the Distance Between Two Nodes in a Binary Tree
  35. 35Find the kth Ancestor of a Node in a Binary Tree
  36. 36Find All Duplicate Subtrees in a Binary Tree

Find Kth Smallest Element using Quickselect



Problem Statement

Given an unsorted array of integers and a number k, your task is to find the kth smallest element in the array using an efficient technique.

This problem can be solved in linear average time using the Quickselect algorithm, which is related to Quicksort but optimized to find a specific order statistic without full sorting.

Examples

Input ArraykOutputDescription
[7, 10, 4, 3, 20, 15]37The 3rd smallest element is 7
[7, 10, 4, 3, 20, 15]410The 4th smallest element is 10
[1]11Single element, return it directly
[9, 8, 7, 6]16Smallest element is 6
[5, 3, 2, 4, 1]55Largest element (k = n)
[2, 1]3-1k exceeds array length
[]1-1Empty array, return error or -1

Solution

The Quickselect algorithm is a powerful tool to find the kth smallest element in an unsorted array without fully sorting it. It works efficiently in most cases, running in O(n) average time.

Understanding the Goal

If you were to sort the array, the kth smallest element would be at index k - 1. But full sorting takes O(n log n) time. Quickselect helps us get the answer without sorting everything.

How It Works

The algorithm works by choosing a pivot (often randomly) and partitioning the array into three groups:

  • Lows: all elements less than the pivot
  • Pivots: all elements equal to the pivot
  • Highs: all elements greater than the pivot

Now, depending on the size of these groups, we decide where to continue:

  • If k is less than or equal to the size of lows, then the answer lies in the lows part, and we recursively apply Quickselect there.
  • If k falls within the size of lows + pivots, then the pivot is the kth smallest number—we return it directly.
  • Otherwise, we look into highs, subtracting the size of lows and pivots from k because we’ve skipped over that many smaller elements.

Handling Special Cases

  • If the array is empty or k < 1, return -1 because there's no valid answer.
  • If k is larger than the number of elements in the array, we should also return -1 to indicate it's out of bounds.
  • If the array contains duplicates, the algorithm still works since it accounts for equal-to-pivot elements as a separate group.
  • If the array has only one element, and k = 1, that single element is the answer.

This approach avoids the overhead of full sorting and gives us just the answer we need by narrowing our focus each time.

Visualization

Algorithm Steps

  1. Given an array of numbers and an integer k (1-indexed), the goal is to find the kth smallest element.
  2. If the array contains only one element, return that element.
  3. Randomly choose a pivot from the array.
  4. Partition the array into three groups: lows (elements less than the pivot), pivots (elements equal to the pivot), and highs (elements greater than the pivot).
  5. If k is less than or equal to the size of lows, recursively search in lows.
  6. If k is within the size of lows plus pivots, the pivot is the kth smallest element.
  7. Otherwise, recursively search in highs with an updated k (subtracting the sizes of lows and pivots).

Code

Python
Java
JavaScript
C
C++
C#
Kotlin
Swift
Go
Php
import random

def quickselect(arr, k):
    if len(arr) == 1:
        return arr[0]
    pivot = random.choice(arr)
    lows = [x for x in arr if x < pivot]
    highs = [x for x in arr if x > pivot]
    pivots = [x for x in arr if x == pivot]
    if k <= len(lows):
        return quickselect(lows, k)
    elif k <= len(lows) + len(pivots):
        return pivot
    else:
        return quickselect(highs, k - len(lows) - len(pivots))

if __name__ == '__main__':
    arr = [7, 10, 4, 3, 20, 15]
    k = 3
    print("The", k, "th smallest element is:", quickselect(arr, k))

Time Complexity

CaseTime ComplexityExplanation
Best CaseO(n)If the pivot divides the array evenly, each recursive call reduces the problem size by half, leading to linear time complexity.
Average CaseO(n)On average, the random pivot leads to a fairly balanced partition, resulting in linear time complexity for finding the kth element.
Average CaseO(n²)In the worst case (e.g., when the smallest or largest element is always chosen as pivot), the partitioning is highly unbalanced, resulting in quadratic time complexity.

Space Complexity

O(1) (in-place) or O(n) (with extra arrays)

Explanation: If implemented in-place like Lomuto partition, it uses constant space. But if implemented with extra arrays for lows, pivots, and highs, it uses linear space.



Welcome to ProgramGuru

Sign up to start your journey with us

Support ProgramGuru.org

You can support this website with a contribution of your choice.

When making a contribution, mention your name, and programguru.org in the message. Your name shall be displayed in the sponsors list.

PayPal

UPI

PhonePe QR

MALLIKARJUNA M