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