這題標準運用了二分搜尋法,演算法通常需要使用二分思想,即每次能夠排除一半的範圍,快速的找出陣列中所要求的元素位置,這樣時間複雜度可達 O(log n)
,時間複雜度可達 O(n)
,這裡有 JAVA 和 Python 的寫法。
Given an array of integers
nums
sorted in non-decreasing order, find the starting and ending position of a giventarget
value.
Iftarget
is not found in the array, return[-1, -1]
.
You must write an algorithm withO(log n)
runtime complexity.
給定一個不是降序過後的整數陣列
nums
,找到目標值的開始和結束的位置。
如果在陣列裡找不到目標,回傳[-1, -1]
。
你必須寫出一個時間複雜度O(log n)
的算法。
題目連結:https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/
0 <= nums.length <= 105
109 <= nums[i] <= 109
nums
is a non-decreasing array.109 <= target <= 109
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
目標值是 8,所以在陣列裡開始和結束的位置是 3 和 4
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
Input: nums = [], target = 0
Output: [-1,-1]
findFirst
、 findLast
來取得第一個和最後一個符合 target 值的索引。target
小於等於 nums[mid]
,則將 end
更新為 mid - 1
。target
大於 nums[mid]
,則將 start
更新為 mid + 1
。idx
設定為 mid
。target
大於等於 nums[mid]
,則將 start
更新為 mid + 1
。target
小於 nums[mid]
,則將 end
更新為 mid - 1
。idx
設定為 mid
。[注意點] 之所以要用上述中間值的寫法會比較安全,因如果 start 和 end 趨近於最大數時,兩者相加起來的合可能會造成整數溢位
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] result = new int[2];
result[0] = findFirst(nums, target); // target 第一次出現的位置
result[1] = findLast(nums, target); // target 最後一次出現的位置
return result;
}
public int findFirst(int[] nums, int target){
int idx = -1; // 回傳值
int start = 0; // 起點位置
int end = nums.length - 1; // 終點位置
while(start <= end){
int mid = (start + end) / 2; // 中位數
// 一直往陣列的左側找到底,找到第一次出現的位置
if(target <= nums[mid]){
end = mid - 1; // 重新定義終點,下次回圈找到新的終點停止
}else{
start = mid + 1; // 重新定義起點,下次回圈從新的起點開始
}
if (target == nums[mid]) { // 陣列裡確定有 target
idx = mid;
}
}
return idx;
}
public int findLast(int[] nums, int target){
int idx = -1;
int start = 0;
int end = nums.length - 1;
while (start <= end){
int mid = (start + end) / 2;
// 一直往陣列的右側找到底,找到最後一次出現的位置
if(target >= nums[mid]){
start = mid + 1;
}else{
end = mid - 1;
}
if(target == nums[mid]){
idx = mid;
}
}
return idx;
}
}
使用了和 Java 一樣的邏輯執行,換成 Python 的寫法。
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
result = [self.findFirst(nums, target), self.findLast(nums, target)]
return result
def findFirst(self, nums: List[int], target: int) -> int:
idx = -1
start, end = 0, len(nums) - 1
while start <= end:
mid = (start + end) // 2
if target <= nums[mid]:
end = mid - 1
else:
start = mid + 1
if target == nums[mid]:
idx = mid
return idx
def findLast(self, nums: List[int], target: int) -> int:
idx = -1
start, end = 0, len(nums) - 1
while start <= end:
mid = (start + end) // 2
if target >= nums[mid]:
start = mid + 1
else:
end = mid - 1
if target == nums[mid]:
idx = mid
return idx
Language | Runtime | Memory |
---|---|---|
Java | 0ms | 45.74MB |
Python | 75ms | 17.81MB |
(新手上路,如有錯誤請友善告知,感謝)
Blog
https://chris81051.github.io/2024/01/21/Leetcode-34-Find-First-and-last-Position-of-Element-in-Sorted-Array-Java-Python/
有分享技術文章、科技新聞、日常生活,歡迎一起討論