-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathMagicIndex.cs
72 lines (60 loc) · 2.22 KB
/
MagicIndex.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System;
namespace PracticeQuestionsSharp.Exercises.Dynamic_Programming
{
//A magic index in a given array A[0...n-1] is defined to be an index such that
// A[i] == i. Given a sorted array of distinct integers, write a method to find
// a magic index, if one exists, in array A.
public static class MagicIndex
{
//Brute force with small optimization
public static int FindMagicIndex(int[] arr)
{
for (int i = 0; i < arr.Length; ++i)
{
if (arr[i] == i) return i;
if (arr[i] > i) i = arr[i];
}
return -1;
}
public static int FindMagicIndexBinarySearch(int[] arr)
{
int max = arr.Length - 1;
int min = 0;
while (min <= max)
{
int mid = min + (max - min) / 2;
int comparison = mid.CompareTo(arr[mid]);
switch (comparison)
{
case 1:
min = mid + 1;
break;
case -1:
max = mid - 1;
break;
case 0:
return mid;
}
}
return -1;
}
//Follow up. What if the values are not distinct?
public static int FindNonDistinctMagicIndexBinarySearch(int[] arr)
{
return CheckArrSubSection(arr, 0, arr.Length - 1);
}
//Since numbers are not distinct we have to check both sides, we can only exclude numbers
// whose index is lower/higher than the next min/max since it's ordered.
private static int CheckArrSubSection(int[] arr, int min, int max)
{
if (min > max) return -1;
int mid = min + (max - min) / 2;
if (mid.CompareTo(arr[mid]) == 0) return mid;
int leftResult = CheckArrSubSection(arr, min, Math.Min(mid - 1, arr[mid]));
if (leftResult != -1) return leftResult;
int rightResult = CheckArrSubSection(arr, Math.Max(mid + 1, arr[mid]), max);
if (rightResult != -1) return rightResult;
return -1;
}
}
}