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

Search in Rotated Sorted Array (with Duplicates)
Optimal Binary Search



Problem Statement

You are given a rotated sorted array that may contain duplicate values, and a target number key. Your task is to determine whether the key exists in the array or not.

The array was originally sorted in ascending order but then rotated at some pivot point. Due to rotation and the presence of duplicates, the structure can be irregular.

Your goal: Return true if the key is found, else return false.

Examples

Input ArrayKeyOutputDescription
[2, 5, 6, 0, 0, 1, 2]0trueKey is present after rotation with duplicates
[2, 5, 6, 0, 0, 1, 2]3falseKey not present in the array
[1, 0, 1, 1, 1]0trueKey is present, array has many duplicates
[1, 1, 1, 1, 1]2falseAll values are duplicates, key is not present
[1]1trueSingle-element array with match
[1]0falseSingle-element array without match
[]5falseEmpty array, so key cannot be present

Solution

To solve this problem, we need to search for a given number in a rotated sorted array that may include duplicate values. At first glance, the problem seems similar to regular binary search, but rotation and duplicates introduce a few complications.

What Makes This Problem Tricky?

  • Rotation breaks the normal order of sorting at some pivot point.
  • Duplicates make it harder to decide which half of the array is sorted.

How Do We Approach It?

We use a variation of binary search that works even when we encounter duplicates. Here's how we handle different situations:

Case 1: Middle element matches the key

If the middle element is equal to the key, we return true. That’s the best-case scenario.

Case 2: Duplicates at the boundaries

If the elements at the start, mid, and end are all equal, we can’t tell which side is sorted. In this case, we safely move the start pointer forward and end pointer backward to reduce the ambiguity.

Case 3: Left half is sorted

If the left half from start to mid is sorted, we check if the key lies in that range. If it does, we search in the left half; otherwise, we move to the right half.

Case 4: Right half is sorted

If the right half from mid to end is sorted, and if the key lies in that part, we shift our search to the right half. Otherwise, we go left.

What If the Array is Empty?

If the array has no elements, the key can’t be found, so we simply return false.

Final Outcome

Using this strategy ensures we consider all scenarios, including:

  • Rotated sorted arrays
  • Completely sorted arrays
  • Arrays with lots of duplicates
  • Edge cases like empty or single-element arrays

This method still works in logarithmic time in the average case but may degrade to O(n) when many duplicates exist.

Visualization

Algorithm Steps

  1. Start with start = 0 and end = n - 1.
  2. While start ≤ end, compute mid = start + (end - start) / 2.
  3. If arr[mid] == key, return true.
  4. If arr[start] == arr[mid] == arr[end], increment start and decrement end.
  5. Else, check if left half is sorted (i.e., arr[start] ≤ arr[mid]).
  6. → If yes, and arr[start] ≤ key < arr[mid], move end = mid - 1.
  7. → Else, move start = mid + 1.
  8. If right half is sorted (i.e., arr[mid] ≤ arr[end]):
  9. → If arr[mid] < key ≤ arr[end], move start = mid + 1.
  10. → Else, move end = mid - 1.
  11. Repeat until found or range becomes invalid.

Code

Java
Python
JavaScript
C
C++
C#
Kotlin
Swift
Go
Php
public class RotatedArraySearchWithDuplicates {
  public static boolean search(int[] arr, int key) {
    int start = 0, end = arr.length - 1;

    while (start <= end) {
      int mid = start + (end - start) / 2;
      if (arr[mid] == key) return true;

      // Handle duplicates: shrink window
      if (arr[start] == arr[mid] && arr[mid] == arr[end]) {
        start++;
        end--;
      }
      // Left half is sorted
      else if (arr[start] <= arr[mid]) {
        if (arr[start] <= key && key < arr[mid]) {
          end = mid - 1;
        } else {
          start = mid + 1;
        }
      }
      // Right half is sorted
      else {
        if (arr[mid] < key && key <= arr[end]) {
          start = mid + 1;
        } else {
          end = mid - 1;
        }
      }
    }
    return false;
  }

  public static void main(String[] args) {
    int[] arr = {2, 5, 6, 0, 0, 1, 2};
    int key = 0;
    System.out.println("Is Key Present: " + search(arr, key));
  }
}

Time Complexity

CaseTime ComplexityExplanation
Best CaseO(1)Key is found at the middle index in the first check.
Average CaseO(log n)Binary search generally divides the array in half at each step.
Average CaseO(n)When duplicates exist everywhere, we might need to linearly shrink the search range.

Space Complexity

O(1)

Explanation: Only a constant number of pointers are used for binary search, without extra space.



Welcome to ProgramGuru

Sign up to start your journey with us

Support ProgramGuru.org

Mention your name, and programguru.org in the message. Your name shall be displayed in the sponsers list.

PayPal

UPI

PhonePe QR

MALLIKARJUNA M