Skip to content

Commit fc7a458

Browse files
authored
feat: update solutions to lc problem: No.0034 (#3793)
1 parent f0e6867 commit fc7a458

File tree

3 files changed

+49
-141
lines changed

3 files changed

+49
-141
lines changed

Diff for: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md

+22-69
Original file line numberDiff line numberDiff line change
@@ -64,58 +64,7 @@ tags:
6464

6565
我们可以进行两次二分查找,分别查找出左边界和右边界。
6666

67-
时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。其中 $n$ 是数组 $nums$ 的长度。
68-
69-
以下是二分查找的两个通用模板:
70-
71-
模板 1:
72-
73-
```java
74-
boolean check(int x) {
75-
}
76-
77-
int search(int left, int right) {
78-
while (left < right) {
79-
int mid = (left + right) >> 1;
80-
if (check(mid)) {
81-
right = mid;
82-
} else {
83-
left = mid + 1;
84-
}
85-
}
86-
return left;
87-
}
88-
```
89-
90-
模板 2:
91-
92-
```java
93-
boolean check(int x) {
94-
}
95-
96-
int search(int left, int right) {
97-
while (left < right) {
98-
int mid = (left + right + 1) >> 1;
99-
if (check(mid)) {
100-
left = mid;
101-
} else {
102-
right = mid - 1;
103-
}
104-
}
105-
return left;
106-
}
107-
```
108-
109-
做二分题目时,可以按照以下套路:
110-
111-
1. 写出循环条件 $left < right$;
112-
1. 循环体内,不妨先写 $mid = \lfloor \frac{left + right}{2} \rfloor$;
113-
1. 根据具体题目,实现 $check()$ 函数(有时很简单的逻辑,可以不定义 $check$),想一下究竟要用 $right = mid$(模板 $1$) 还是 $left = mid$(模板 $2$);
114-
    - 如果 $right = mid$,那么写出 else 语句 $left = mid + 1$,并且不需要更改 mid 的计算,即保持 $mid = \lfloor \frac{left + right}{2} \rfloor$;
115-
    - 如果 $left = mid$,那么写出 else 语句 $right = mid - 1$,并且在 $mid$ 计算时补充 +1,即 $mid = \lfloor \frac{left + right + 1}{2} \rfloor$;
116-
1. 循环结束时, $left$ 与 $right$ 相等。
117-
118-
注意,这两个模板的优点是始终保持答案位于二分区间内,二分结束条件对应的值恰好在答案所处的位置。 对于可能无解的情况,只要判断二分结束后的 $left$ 或者 $right$ 是否满足题意即可。
67+
时间复杂度 $O(\log n)$,其中 $n$ 是数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。
11968

12069
<!-- tabs:start -->
12170

@@ -162,7 +111,9 @@ public:
162111
vector<int> searchRange(vector<int>& nums, int target) {
163112
int l = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
164113
int r = lower_bound(nums.begin(), nums.end(), target + 1) - nums.begin();
165-
if (l == r) return {-1, -1};
114+
if (l == r) {
115+
return {-1, -1};
116+
}
166117
return {l, r - 1};
167118
}
168119
};
@@ -265,26 +216,28 @@ var searchRange = function (nums, target) {
265216
```php
266217
class Solution {
267218
/**
268-
* @param integer[] $nums
269-
* @param integer $target
270-
* @return integer[]
219+
* @param Integer[] $nums
220+
* @param Integer $target
221+
* @return Integer[]
271222
*/
272-
273223
function searchRange($nums, $target) {
274-
$min = -1;
275-
$max = -1;
276-
foreach ($nums as $key => $value) {
277-
if ($value == $target) {
278-
if ($min == -1) {
279-
$min = $key;
280-
}
281-
282-
if ($key > $max) {
283-
$max = $key;
224+
$search = function ($x) use ($nums) {
225+
$left = 0;
226+
$right = count($nums);
227+
while ($left < $right) {
228+
$mid = intdiv($left + $right, 2);
229+
if ($nums[$mid] >= $x) {
230+
$right = $mid;
231+
} else {
232+
$left = $mid + 1;
284233
}
285234
}
286-
}
287-
return [$min, $max];
235+
return $left;
236+
};
237+
238+
$l = $search($target);
239+
$r = $search($target + 1);
240+
return $l === $r ? [-1, -1] : [$l, $r - 1];
288241
}
289242
}
290243
```

Diff for: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md

+23-70
Original file line numberDiff line numberDiff line change
@@ -52,60 +52,9 @@ tags:
5252

5353
### Solution 1: Binary Search
5454

55-
We can perform binary search twice to find the left and right boundaries respectively.
55+
We can perform two binary searches to find the left boundary and the right boundary.
5656

57-
The time complexity is $O(\log n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array $nums$.
58-
59-
Below are two general templates for binary search:
60-
61-
Template 1:
62-
63-
```java
64-
boolean check(int x) {
65-
}
66-
67-
int search(int left, int right) {
68-
while (left < right) {
69-
int mid = (left + right) >> 1;
70-
if (check(mid)) {
71-
right = mid;
72-
} else {
73-
left = mid + 1;
74-
}
75-
}
76-
return left;
77-
}
78-
```
79-
80-
Template 2:
81-
82-
```java
83-
boolean check(int x) {
84-
}
85-
86-
int search(int left, int right) {
87-
while (left < right) {
88-
int mid = (left + right + 1) >> 1;
89-
if (check(mid)) {
90-
left = mid;
91-
} else {
92-
right = mid - 1;
93-
}
94-
}
95-
return left;
96-
}
97-
```
98-
99-
When doing binary search problems, you can follow the following routine:
100-
101-
1. Write out the loop condition $left < right$;
102-
2. Inside the loop, you might as well write $mid = \lfloor \frac{left + right}{2} \rfloor$ first;
103-
3. According to the specific problem, implement the $check()$ function (sometimes the logic is very simple, you can not define $check$), think about whether to use $right = mid$ (Template $1$) or $left = mid$ (Template $2$);
104-
- If $right = mid$, then write the else statement $left = mid + 1$, and there is no need to change the calculation of $mid$, that is, keep $mid = \lfloor \frac{left + right}{2} \rfloor$;
105-
- If $left = mid$, then write the else statement $right = mid - 1$, and add +1 when calculating $mid$, that is, $mid = \lfloor \frac{left + right + 1}{2} \rfloor$;
106-
4. When the loop ends, $left$ equals $right$.
107-
108-
Note that the advantage of these two templates is that they always keep the answer within the binary search interval, and the value corresponding to the end condition of the binary search is exactly at the position of the answer. For the case that may have no solution, just check whether the $left$ or $right$ after the binary search ends satisfies the problem.
57+
The time complexity is $O(\log n)$, where $n$ is the length of the array $\textit{nums}$. The space complexity is $O(1)$.
10958

11059
<!-- tabs:start -->
11160

@@ -152,7 +101,9 @@ public:
152101
vector<int> searchRange(vector<int>& nums, int target) {
153102
int l = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
154103
int r = lower_bound(nums.begin(), nums.end(), target + 1) - nums.begin();
155-
if (l == r) return {-1, -1};
104+
if (l == r) {
105+
return {-1, -1};
106+
}
156107
return {l, r - 1};
157108
}
158109
};
@@ -255,26 +206,28 @@ var searchRange = function (nums, target) {
255206
```php
256207
class Solution {
257208
/**
258-
* @param integer[] $nums
259-
* @param integer $target
260-
* @return integer[]
209+
* @param Integer[] $nums
210+
* @param Integer $target
211+
* @return Integer[]
261212
*/
262-
263213
function searchRange($nums, $target) {
264-
$min = -1;
265-
$max = -1;
266-
foreach ($nums as $key => $value) {
267-
if ($value == $target) {
268-
if ($min == -1) {
269-
$min = $key;
270-
}
271-
272-
if ($key > $max) {
273-
$max = $key;
214+
$search = function ($x) use ($nums) {
215+
$left = 0;
216+
$right = count($nums);
217+
while ($left < $right) {
218+
$mid = intdiv($left + $right, 2);
219+
if ($nums[$mid] >= $x) {
220+
$right = $mid;
221+
} else {
222+
$left = $mid + 1;
274223
}
275224
}
276-
}
277-
return [$min, $max];
225+
return $left;
226+
};
227+
228+
$l = $search($target);
229+
$r = $search($target + 1);
230+
return $l === $r ? [-1, -1] : [$l, $r - 1];
278231
}
279232
}
280233
```

Diff for: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ class Solution {
33
vector<int> searchRange(vector<int>& nums, int target) {
44
int l = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
55
int r = lower_bound(nums.begin(), nums.end(), target + 1) - nums.begin();
6-
if (l == r) return {-1, -1};
6+
if (l == r) {
7+
return {-1, -1};
8+
}
79
return {l, r - 1};
810
}
9-
};
11+
};

0 commit comments

Comments
 (0)