二分探索
704. 二分探索
トピック
トピックリンク
n 個の要素とターゲット値 target を持つ順序付き (昇順) 整数配列 nums を指定して、nums でターゲットを検索し、ターゲット値が存在する場合は添字を返し、存在しない場合は -1 を返す関数を作成します。
入力: nums = [-1,0,3,5,9,12]、ターゲット = 9
出力: 4
説明: 9 は添え字 4 とともに nums に表示されます。
入力: nums = [-1,0,3,5,9,12]、ターゲット = 2
出力: -1
説明: nums に 2 が存在しないため、-1 を返します。
達成
class Solution {
public int search(int[] nums,int target) {
if(target<nums[0]||target>nums[nums.length-1]) // nums.length
return -1;
int left=0;
int right=nums.length - 1;
while(left<=right){
int mid=(left+right)/2;
//mid = left + ((right - left) >> 1);
if (nums[mid]==target)
return mid;
else if (nums[mid]<target)
left=mid+1;
else if (nums[mid]>target)
right=mid-1;
}
return -1;
}
}
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left = 0;
right = len(nums)-1;
while left<=right:
mid=(right+left)/2
if nums[mid]>target:
right=mid-1
elif nums[mid]<target:
left=mid+1
else:
return middle
return -1
要約する
- 順序付き配列、重複要素なし -> 二分検索
- [左、右] 、ながら (左 <= 右) 、右 = 中央 - 1 # 左 = 右のとき、 [左、右] 意識义
- [左、右)、右=nums.length、while (左 < 右)、右=中央
35. 挿入位置の検索
トピック
ソートされた配列とターゲット値を指定すると、配列内でターゲット値を検索し、そのインデックスを返します。配列内に対象の値が存在しない場合は、順番に挿入される位置を返します。
時間計算量が O(log n) のアルゴリズムを使用してください。
入力: 数値 = [1,3,5,6]、ターゲット = 5
出力: 2
入力: 数値 = [1,3,5,6]、ターゲット = 2
出力: 1
入力: 数値 = [1,3,5,6]、ターゲット = 7
出力: 4
達成
- 存在しません。右に戻る+1
class Solution {
public int searchInsert(int[] nums, int target) {
int left=0;
int right=nums.length - 1;
while(left<=right){
int mid=(left+right)/2;
//mid = left + ((right - left) >> 1);
if (nums[mid]==target)
return mid;
else if (nums[mid]<target)
left=mid+1;
else if (nums[mid]>target)
right=mid-1;
}
return right+1;
}
}
34. ソートされた配列内の要素の最初と最後の位置を見つける
トピック
降順でない整数配列 nums と目標値 target が与えられます。指定されたターゲット値が配列内のどこで始まり、どこで終わるかを調べてください。
ターゲット値 target が配列内に存在しない場合は、[-1, -1] を返します。
この問題を解決するには、時間計算量 O(log n) のアルゴリズムを設計して実装する必要があります。
入力: 数値 = [5,7,7,8,8,10]、ターゲット = 8
出力: [3,4]
入力: 数値 = [5,7,7,8,8,10]、ターゲット = 6
出力: [-1,-1]
入力: nums = []、ターゲット = 0
出力: [-1,-1]
達成
class Solution {
public int[] searchRange(int[] nums, int target) {
int index=binarySearch(nums,target);
if(index==-1)
return new int[] {
-1,-1}; //新建数组
int left=index;
int right=index;
while (left-1>= 0 && nums[left-1]==nums[index])
left--;
while (right+1< nums.length && nums[right+1]==nums[index])
right++;
return new int[] {
left, right};
}
public int binarySearch(int[] nums, int target){
int left=0;
int right=nums.length - 1;
while(left<=right){
int mid=(left+right)/2;
//mid = left + ((right - left) >> 1);
if (nums[mid]==target)
return mid;
else if (nums[mid]<target)
left=mid+1;
else if (nums[mid]>target)
right=mid-1;
}
return -1;
}
}
69.x の平方根
トピック
トピックリンク
負でない整数 x を指定して、x の算術平方根を計算して返します。
戻り値の型は整数であるため、結果の整数部分のみが保持され、小数部分は破棄されます。
注: pow(x, 0.5) や x ** 0.5 などの組み込みの指数関数や演算子は使用できません。
入力: x = 4
出力: 2
入力: x = 8
出力: 2
説明: 8 の算術平方根は 2.82842…、戻り値の型が整数であるため、小数部分は四捨五入されます。
達成
class Solution {
public int mySqrt(int x) {
int left=0;
int right=x;
int ans=-1;
while (left<=right) {
int mid=(left+right) / 2;
if ((long)mid*mid<=x) {
ans=mid;
left=mid+1;
}
else
right=mid-1;
}
return ans;
}
}
367. 効率的な完全二乗法
トピック
正の整数が与えられます。num が完全な正方形の場合は true、それ以外の場合は false を返します。
完全二乗は、ある整数の 2 乗として記述できる整数です。言い換えれば、それはある整数とそれ自体の積として書くことができます。
sqrt などの組み込みライブラリ関数は使用できません。
入力: num = 16
出力: true
説明: 4 * 4 = 16 であり、4 は整数であるため、true を返します。
入力: num = 14
出力: false
説明: 3.742 * 3.742 = 14 ですが、3.742 は整数ではないため、false を返します。
達成
class Solution {
public boolean isPerfectSquare(int num) {
int left=0, right=num;
while(left<=right){
int mid=(left+right)/2;
if((long)mid*mid==num)
return true;
else if((long)mid*mid>num)
right=mid-1;
else
left=mid+1;
}
return false;
}
}