|
10 | 10 |
|
11 | 11 | <ul>
|
12 | 12 | <li><code>int compareSub(int l, int r, int x, int y)</code>:其中 <code>0 <= l, r, x, y < ArrayReader.length()</code>, <code>l <= r</code> 且 <code>x <= y</code>。这个函数比较子数组 <code>arr[l..r]</code> 与子数组 <code>arr[x..y]</code> 的和。该函数返回:
|
13 |
| - |
14 | 13 | <ul>
|
15 | 14 | <li><strong>1</strong> 若 <code>arr[l]+arr[l+1]+...+arr[r] > arr[x]+arr[x+1]+...+arr[y]</code> 。</li>
|
16 | 15 | <li><strong>0</strong> 若 <code>arr[l]+arr[l+1]+...+arr[r] == arr[x]+arr[x+1]+...+arr[y]</code> 。</li>
|
@@ -61,27 +60,165 @@ reader.compareSub(4, 4, 5, 5) // 返回 1。因此,可以确定 arr[4] 是数
|
61 | 60 | <li><code>arr</code> 中除一个最大元素外,其余所有元素都相等。</li>
|
62 | 61 | </ul>
|
63 | 62 |
|
64 |
| - |
65 | 63 | ## 解法
|
66 | 64 |
|
67 | 65 | <!-- 这里可写通用的实现逻辑 -->
|
68 | 66 |
|
| 67 | +三分查找。 |
| 68 | + |
| 69 | +前两部分数量相等,进行 `compareSub` 比较。 |
| 70 | + |
69 | 71 | <!-- tabs:start -->
|
70 | 72 |
|
71 | 73 | ### **Python3**
|
72 | 74 |
|
73 | 75 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
74 | 76 |
|
75 | 77 | ```python
|
76 |
| - |
| 78 | +# """ |
| 79 | +# This is ArrayReader's API interface. |
| 80 | +# You should not implement it, or speculate about its implementation |
| 81 | +# """ |
| 82 | +#class ArrayReader(object): |
| 83 | +# # Compares the sum of arr[l..r] with the sum of arr[x..y] |
| 84 | +# # return 1 if sum(arr[l..r]) > sum(arr[x..y]) |
| 85 | +# # return 0 if sum(arr[l..r]) == sum(arr[x..y]) |
| 86 | +# # return -1 if sum(arr[l..r]) < sum(arr[x..y]) |
| 87 | +# def compareSub(self, l: int, r: int, x: int, y: int) -> int: |
| 88 | +# |
| 89 | +# # Returns the length of the array |
| 90 | +# def length(self) -> int: |
| 91 | +# |
| 92 | + |
| 93 | + |
| 94 | +class Solution: |
| 95 | + def getIndex(self, reader: 'ArrayReader') -> int: |
| 96 | + left, right = 0, reader.length() - 1 |
| 97 | + while left < right: |
| 98 | + t1, t2, t3 = left, left + (right - left) // 3, left + ((right - left) // 3) * 2 + 1 |
| 99 | + cmp = reader.compareSub(t1, t2, t2 + 1, t3) |
| 100 | + if cmp == 0: |
| 101 | + left = t3 + 1 |
| 102 | + elif cmp == 1: |
| 103 | + right = t2 |
| 104 | + else: |
| 105 | + left, right = t2 + 1, t3 |
| 106 | + return left |
77 | 107 | ```
|
78 | 108 |
|
79 | 109 | ### **Java**
|
80 | 110 |
|
81 | 111 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
82 | 112 |
|
83 | 113 | ```java
|
| 114 | +/** |
| 115 | + * // This is ArrayReader's API interface. |
| 116 | + * // You should not implement it, or speculate about its implementation |
| 117 | + * interface ArrayReader { |
| 118 | + * // Compares the sum of arr[l..r] with the sum of arr[x..y] |
| 119 | + * // return 1 if sum(arr[l..r]) > sum(arr[x..y]) |
| 120 | + * // return 0 if sum(arr[l..r]) == sum(arr[x..y]) |
| 121 | + * // return -1 if sum(arr[l..r]) < sum(arr[x..y]) |
| 122 | + * public int compareSub(int l, int r, int x, int y) {} |
| 123 | + * |
| 124 | + * // Returns the length of the array |
| 125 | + * public int length() {} |
| 126 | + * } |
| 127 | + */ |
| 128 | + |
| 129 | +class Solution { |
| 130 | + public int getIndex(ArrayReader reader) { |
| 131 | + int left = 0, right = reader.length() - 1; |
| 132 | + while (left < right) { |
| 133 | + int t1 = left, t2 = left + (right - left) / 3, t3 = left + (right - left) / 3 * 2 + 1; |
| 134 | + int cmp = reader.compareSub(t1, t2, t2 + 1, t3); |
| 135 | + if (cmp == 0) { |
| 136 | + left = t3 + 1; |
| 137 | + } else if (cmp == 1) { |
| 138 | + right = t2; |
| 139 | + } else { |
| 140 | + left = t2 + 1; |
| 141 | + right = t3; |
| 142 | + } |
| 143 | + } |
| 144 | + return left; |
| 145 | + } |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +### **C++** |
| 150 | + |
| 151 | +```cpp |
| 152 | +/** |
| 153 | + * // This is the ArrayReader's API interface. |
| 154 | + * // You should not implement it, or speculate about its implementation |
| 155 | + * class ArrayReader { |
| 156 | + * public: |
| 157 | + * // Compares the sum of arr[l..r] with the sum of arr[x..y] |
| 158 | + * // return 1 if sum(arr[l..r]) > sum(arr[x..y]) |
| 159 | + * // return 0 if sum(arr[l..r]) == sum(arr[x..y]) |
| 160 | + * // return -1 if sum(arr[l..r]) < sum(arr[x..y]) |
| 161 | + * int compareSub(int l, int r, int x, int y); |
| 162 | + * |
| 163 | + * // Returns the length of the array |
| 164 | + * int length(); |
| 165 | + * }; |
| 166 | + */ |
| 167 | + |
| 168 | +class Solution { |
| 169 | +public: |
| 170 | + int getIndex(ArrayReader &reader) { |
| 171 | + int left = 0, right = reader.length() - 1; |
| 172 | + while (left < right) { |
| 173 | + int t1 = left, t2 = left + (right - left) / 3, t3 = left + (right - left) / 3 * 2 + 1; |
| 174 | + int cmp = reader.compareSub(t1, t2, t2 + 1, t3); |
| 175 | + if (cmp == 0) { |
| 176 | + left = t3 + 1; |
| 177 | + } else if (cmp == 1) { |
| 178 | + right = t2; |
| 179 | + } else { |
| 180 | + left = t2 + 1; |
| 181 | + right = t3; |
| 182 | + } |
| 183 | + } |
| 184 | + return left; |
| 185 | + } |
| 186 | +}; |
| 187 | +``` |
84 | 188 |
|
| 189 | +### **Go** |
| 190 | +
|
| 191 | +```go |
| 192 | +/** |
| 193 | + * // This is the ArrayReader's API interface. |
| 194 | + * // You should not implement it, or speculate about its implementation |
| 195 | + * type ArrayReader struct { |
| 196 | + * } |
| 197 | + * // Compares the sum of arr[l..r] with the sum of arr[x..y] |
| 198 | + * // return 1 if sum(arr[l..r]) > sum(arr[x..y]) |
| 199 | + * // return 0 if sum(arr[l..r]) == sum(arr[x..y]) |
| 200 | + * // return -1 if sum(arr[l..r]) < sum(arr[x..y]) |
| 201 | + * func (this *ArrayReader) compareSub(l, r, x, y int) int {} |
| 202 | + * |
| 203 | + * // Returns the length of the array |
| 204 | + * func (this *ArrayReader) length() int {} |
| 205 | + */ |
| 206 | +
|
| 207 | +func getIndex(reader *ArrayReader) int { |
| 208 | + left, right := 0, reader.length()-1 |
| 209 | + for left < right { |
| 210 | + t1, t2, t3 := left, left+(right-left)/3, left+(right-left)/3*2+1 |
| 211 | + cmp := reader.compareSub(t1, t2, t2+1, t3) |
| 212 | + if cmp == 0 { |
| 213 | + left = t3 + 1 |
| 214 | + } else if cmp == 1 { |
| 215 | + right = t2 |
| 216 | + } else { |
| 217 | + left, right = t2+1, t3 |
| 218 | + } |
| 219 | + } |
| 220 | + return left |
| 221 | +} |
85 | 222 | ```
|
86 | 223 |
|
87 | 224 | ### **...**
|
|
0 commit comments