1
+ using System ;
2
+ using System . Linq ;
3
+
4
+ class Range
5
+ {
6
+ public static Range Empty = new Range ( new int [ 0 ] , 0 , - 1 ) ;
7
+
8
+ public readonly int [ ] Numbers ;
9
+ public readonly int LeftIndex ;
10
+ public readonly int RightIndex ;
11
+
12
+ public int Count { get { return RightIndex - LeftIndex + 1 ; } }
13
+
14
+ public int this [ int index ]
15
+ {
16
+ get
17
+ {
18
+ if ( index >= Count )
19
+ {
20
+ throw new IndexOutOfRangeException ( ) ;
21
+ }
22
+ return Numbers [ LeftIndex + index ] ;
23
+ }
24
+ }
25
+
26
+ public Range ( int [ ] numbers ) : this ( numbers , 0 , numbers . Length - 1 )
27
+ {
28
+ }
29
+
30
+ public Range ( int [ ] numbers , int leftIndex , int rightIndex )
31
+ {
32
+ Numbers = numbers ;
33
+ LeftIndex = leftIndex ;
34
+ RightIndex = rightIndex ;
35
+ if ( RightIndex < LeftIndex ) RightIndex = LeftIndex - 1 ;
36
+ }
37
+
38
+ public Range GetSubRange ( int lowerBound , int upperBound )
39
+ {
40
+ if ( lowerBound > upperBound ) return Empty ;
41
+ var leftIndex = lowerBound == int . MinValue ? LeftIndex : Search ( lowerBound ) ;
42
+ var rightIndex = upperBound == int . MaxValue ? RightIndex : Search ( upperBound + 1 ) - 1 ;
43
+ return new Range ( Numbers , leftIndex , rightIndex ) ;
44
+ }
45
+
46
+ private int Search ( int target )
47
+ {
48
+ var l = 0 ;
49
+ var r = Numbers . Length - 1 ;
50
+ while ( l < r )
51
+ {
52
+ var mid = ( l + r ) / 2 ;
53
+ if ( Numbers [ mid ] < target )
54
+ {
55
+ l = mid + 1 ;
56
+ }
57
+ else
58
+ {
59
+ r = mid ;
60
+ }
61
+ }
62
+ return Numbers [ l ] >= target ? l : l + 1 ;
63
+ }
64
+ }
65
+
66
+ public class Solution {
67
+ public double FindMedianSortedArrays ( int [ ] nums1 , int [ ] nums2 )
68
+ {
69
+ var totalNumbers = nums1 . Length + nums2 . Length ;
70
+ var targetOrder1 = ( totalNumbers + 1 ) / 2 ;
71
+ var targetOrder2 = ( totalNumbers + 2 ) / 2 ;
72
+ var range1 = new Range ( nums1 ) ;
73
+ var range2 = new Range ( nums2 ) ;
74
+ var number1 = FindMedianSortedArrays ( range1 , range2 , targetOrder1 ) ;
75
+ var number2 = targetOrder1 == targetOrder2 ? number1 : FindMedianSortedArrays ( range1 , range2 , targetOrder2 ) ;
76
+ return ( ( double ) number1 + number2 ) / 2 ;
77
+ }
78
+
79
+ private int FindMedianSortedArrays ( Range range1 , Range range2 , int targetOrder )
80
+ {
81
+ if ( range1 . Count == 0 )
82
+ {
83
+ return range2 [ targetOrder - 1 ] ;
84
+ }
85
+ if ( range2 . Count == 0 )
86
+ {
87
+ return range1 [ targetOrder - 1 ] ;
88
+ }
89
+
90
+ var midNumber = range1 [ ( range1 . Count - 1 ) / 2 ] ;
91
+ var midRanges = new [ ] { range1 . GetSubRange ( midNumber , midNumber ) , range2 . GetSubRange ( midNumber , midNumber ) } ;
92
+ var leftRanges = new [ ]
93
+ {
94
+ new Range ( range1 . Numbers , range1 . LeftIndex , midRanges [ 0 ] . LeftIndex - 1 ) ,
95
+ new Range ( range2 . Numbers , range2 . LeftIndex , midRanges [ 1 ] . LeftIndex - 1 )
96
+ } ;
97
+ var rightRanges = new [ ]
98
+ {
99
+ new Range ( range1 . Numbers , midRanges [ 0 ] . RightIndex + 1 , range1 . RightIndex ) ,
100
+ new Range ( range2 . Numbers , midRanges [ 1 ] . RightIndex + 1 , range2 . RightIndex )
101
+ } ;
102
+
103
+ var leftCount = leftRanges . Sum ( r => r . Count ) ;
104
+ var midCount = midRanges . Sum ( r => r . Count ) ;
105
+ var rightCount = rightRanges . Sum ( r => r . Count ) ;
106
+
107
+ if ( leftCount == 0 && rightCount == 0 )
108
+ {
109
+ return midNumber ;
110
+ }
111
+ if ( leftCount >= targetOrder )
112
+ {
113
+ return FindMedianSortedArrays ( leftRanges [ 0 ] , leftRanges [ 1 ] , targetOrder ) ;
114
+ }
115
+ if ( leftCount + midCount >= targetOrder )
116
+ {
117
+ return FindMedianSortedArrays ( midRanges [ 0 ] , midRanges [ 1 ] , targetOrder - leftCount ) ;
118
+ }
119
+ return FindMedianSortedArrays ( rightRanges [ 0 ] , rightRanges [ 1 ] , targetOrder - leftCount - midCount ) ;
120
+ }
121
+ }
0 commit comments