国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

代碼隨想錄 LeetCode數(shù)組篇 二分查找

這篇具有很好參考價(jià)值的文章主要介紹了代碼隨想錄 LeetCode數(shù)組篇 二分查找。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


# (簡單)704. 二分查找

代碼隨想錄 LeetCode數(shù)組篇 二分查找

題目鏈接

代碼隨想錄 - 二分查找思路

二分查找,思路很簡單,但是在while循環(huán)left和right的比較是寫<=還是<,還有right=mid還是right=mid-1容易混淆

需要想清楚對區(qū)間的定義,是[left,right],還是[left,right)

代碼隨想錄 LeetCode數(shù)組篇 二分查找

代碼隨想錄 LeetCode數(shù)組篇 二分查找
代碼隨想錄 LeetCode數(shù)組篇 二分查找

代碼隨想錄 LeetCode數(shù)組篇 二分查找
代碼隨想錄 LeetCode數(shù)組篇 二分查找

(版本一,左閉右閉版本)

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid;
        while (left <= right) {
            mid = left + ((right-left)/2);//防止溢出
            if (nums[mid] == target) {
                return mid;
            }
            if (target > nums[mid]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }
}

(版本二,左閉右開)

class Solution {
    public int search(int[] nums, int target) {

        //避免當(dāng)target小于nums[0] 或者大于 nums[nums.length-1]時(shí) 多次循環(huán)
        if (target < nums[0] || target > nums[nums.length - 1]) {
            return -1;
        }

        int left = 0;
        int right = nums.length;
        int mid;
        while (left < right) {
            mid = left + ((right - left) >> 1);
            if (nums[mid] == target) {
                return mid;
            }
            if (target > nums[mid]) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return -1;
    }
}

(簡單)35. 搜索插入位置

題目鏈接

代碼隨想錄 LeetCode數(shù)組篇 二分查找

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if (nums[mid] == target) {
                return mid;
            }
            if (target > nums[mid]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return left;//right+1
    }
}

(*中等)34. 在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置

代碼隨想錄 LeetCode數(shù)組篇 二分查找
題目鏈接

我的思路:按照傳統(tǒng)二分查找的方式,找到等于target的數(shù)組的下標(biāo),然后向兩邊擴(kuò)展,如果沒找到直接返回[-1,-1]

代碼隨想錄 LeetCode數(shù)組篇 二分查找

class Solution {

    public int[] searchRange(int[] nums, int target) {

        //如果數(shù)組長度是0,則不用判斷
        if (nums == null || nums.length == 0) {
            return new int[]{-1, -1};
        }

        //如果target的值小于第一個(gè)元素或者大于最后一個(gè)元素,也不用判斷
        if ((target < nums[0]) || (target > nums[nums.length - 1])) {
            return new int[]{-1, -1};
        }

        int res = search(nums, target);
        if (res == -1) {
            return new int[]{-1, -1};
        }
        int left = res;
        int right = res;
        while ((left >= 0) && (nums[left] == nums[res])) {
            left--;
        }
        while ((right < nums.length) && (nums[right] == nums[res])) {
            right++;
        }
        return new int[]{left + 1, right - 1};
    }

    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if (target == nums[mid]) {
                return mid;
            }
            if (target > nums[mid]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }
}

看了官方的解題思路,是找出數(shù)組中【第一個(gè)等于target的位置(leftIdx)】和【第一個(gè)大于target的位置減一(rightIdx)】

二分查找中

  • 尋找leftIdx即為在數(shù)組中尋找第一個(gè)大于等于 target的下標(biāo)
  • 尋找rightIdx即為在數(shù)組中尋找第一個(gè)大于 target的下標(biāo),然后減一

二者的判斷條件不同,為了代碼的復(fù)用,定義一個(gè)函數(shù),其中包含布爾類型的lower參數(shù),該參數(shù)為true時(shí),則查找第一個(gè)大于等于target的下標(biāo),該參數(shù)為false時(shí),則查找第一個(gè)大于target的下標(biāo)

最后,因?yàn)閠arget可能不在數(shù)組中,因此需要重新校驗(yàn)兩個(gè)下標(biāo)leftIdx和rightIdx,看是否符合條件,如果符合,就返回[leftIdx,rightIdx],不符合就返回[-1,-1]
代碼隨想錄 LeetCode數(shù)組篇 二分查找

class Solution {

    public int[] searchRange(int[] nums, int target) {

        //如果數(shù)組長度是0,則不用判斷
        if (nums == null || nums.length == 0) {
            return new int[]{-1, -1};
        }

        //如果target的值小于第一個(gè)元素或者大于最后一個(gè)元素,也不用判斷
        if ((target < nums[0]) || (target > nums[nums.length - 1])) {
            return new int[]{-1, -1};
        }

        int leftIdx = search(nums, target, true);
        int rightIdx = search(nums, target, false) - 1;

        if (leftIdx >= 0 && rightIdx < nums.length && leftIdx <= rightIdx && nums[leftIdx] == target && nums[rightIdx] == target) {
            return new int[]{leftIdx, rightIdx};
        }
        return new int[]{-1, -1};

    }

    public int search(int[] nums, int target, boolean lower) {
        int left = 0;
        int right = nums.length - 1;
        int mid;
        int ans = nums.length;
        while (left <= right) {
            mid = left + ((right - left) >> 1);

            //說明當(dāng)前的mid所在的值比target大,需要縮小范圍
            //找leftIdx,如果target小于nums[mid],縮小范圍
            //如果target==nums[mid],也要縮小范圍,但是會(huì)記錄mid
            //找rightIdx,只要target<nums[mid],縮小范圍
            if (target < nums[mid] || (lower && target == nums[mid])) {
                right = mid - 1;
                ans = mid;
            } else {
                //找rightIdx,只要target < nums[mid] 不成立
                //也就是target=nums[mid]或者target>nums[mid] left都會(huì)變化
                left = mid + 1;
            }
        }
        return ans;
    }
}

(簡單,常見面試題)69. x的平方根

代碼隨想錄 LeetCode數(shù)組篇 二分查找
我的思路,將x的值賦給tmp,將tmp不斷除以2

記錄下面兩個(gè)數(shù),在這兩個(gè)數(shù)之間使用二分查找:

  1. 使得tmp^2小于x的最大的tmp值
  2. 使得tmp^2大于x的最小的tmp值
class Solution {
    public int mySqrt(int x) {
        if (x == 0 || x == 1) {
            return x;
        }

        int pre = x;
        int tmp = x / 2;
        while (tmp > x / tmp) { //原來是 tmp * tmp > x
            pre = tmp;
            tmp /= 2;
        }

        if (tmp == x / tmp) { //原來是 tmp * tmp == x 
            return tmp;
        }

        //pre和tmp之間找到答案,縮小范圍
        return search(x, tmp, pre);
    }

    public int search(int x, int tmp, int pre) {
        int left = tmp;
        int right = pre;
        int mid;
        int ans = tmp;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if (mid == x / mid) { //原來是 mid * mid == x
                return mid;
            }
            if (mid > x / mid) { // 原來是mid * mid > x
                right = mid - 1;
            } else {
                ans = mid;
                left = mid + 1;
            }
        }
        return ans;
    }
}

官網(wǎng)解答,筆記:

在不使用 x \sqrt{x} x ?函數(shù)的情況下,得到x的平方根的整數(shù)部分。一般的思路有以下幾種:

  • 通過其它的數(shù)學(xué)函數(shù)代替平方根函數(shù)得到精確結(jié)果,取整數(shù)部分作為答案
  • 通過數(shù)學(xué)方法得到近似結(jié)果,直接作為答案

方法一 袖珍計(jì)算器算法

【袖珍計(jì)算器算法】是一種用指數(shù)函數(shù)exp和對數(shù)函數(shù)ln代替平方根函數(shù)的方法。通過有限的、可以使用的數(shù)學(xué)函數(shù),得到想要的結(jié)果。

代碼隨想錄 LeetCode數(shù)組篇 二分查找
當(dāng)x=2147395600時(shí), e 1 2 ln ? x e^{\frac{1}{2}\ln x} e21?lnx?的計(jì)算結(jié)果與正確值46340相差 1 0 ? 11 10^{-11} 10?11,這樣在對結(jié)果取整數(shù)部分時(shí),會(huì)得到46339這個(gè)錯(cuò)誤結(jié)果。

因此,在得到結(jié)果的整數(shù)部分ans后,應(yīng)該找出ans與ans+1中哪一個(gè)是真正的答案。

class Solution {
    public int mySqrt(int x) {
        if (x == 0 || x == 1) {
            return x;
        }
        int ans = (int) Math.exp(0.5 * Math.log(x));
        return (long) (ans + 1) * (ans + 1) > x ? ans : ans + 1;
    }
}

方法二 二分查找

由于x平方根的整數(shù)部分ans是滿足 k 2 ≤ x k^2 \leq x k2x的最大k值,因此可以對k進(jìn)行二分查找,從而得到答案

二分查找的下界是1,上界可以粗略的=地設(shè)定為x。在二分查找中的每一步中,我們只需要比較中間元素mid的平方與x的大小關(guān)系,并通過比較的結(jié)果調(diào)整上下界的范圍。由于我們所有的運(yùn)算都是整數(shù)運(yùn)算,所以,不會(huì)存在誤差,因此在得到最終的答案ans后,也就不需要再去嘗試ans+1了。

class Solution {
    public int mySqrt(int x) {
        if (x == 0 || x == 1) {
            return x;
        }
        int left = 1;
        int right = x;
        int mid;
        int ans = -1;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if ((long) mid * mid == x) {
                return mid;
            }
            if ((long) mid * mid < x) {
                ans = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return ans;
    }
}

(簡單) 367. 有效的完全平方數(shù)

代碼隨想錄 LeetCode數(shù)組篇 二分查找
二分查找

class Solution {
    public boolean isPerfectSquare(int num) {
        if (num == 1) {
            return true;
        }
        int left = 1;
        int right = num;
        int mid;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if ((long) mid * mid == num) {
                return true;
            }
            if ((long) mid * mid < num) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return false;
    }
}

當(dāng)然還可以使用內(nèi)置的庫函數(shù)

根據(jù)完全平方數(shù)的性質(zhì),只需要判斷num的平方根x是否為整數(shù)即可。

class Solution {
    public boolean isPerfectSquare(int num) {
        int x = (int) Math.sqrt(num);
        return x * x == num;
    }
}

還有暴力法

如果num為完全平方數(shù),那么一定存在正整數(shù)x滿足x * x = num。于是,可以從1開始遍歷所有的正整數(shù),一直遍歷到46340即可,因?yàn)?span id="n5n3t3z" class="katex--inline"> 2 31 ? 1 ≈ 46340 \sqrt{2^{31}-1} \approx 46340 231?1 ?46340文章來源地址http://www.zghlxwxcb.cn/news/detail-430917.html

class Solution {
    public boolean isPerfectSquare(int num) {
        if (num == 1) {
            return true;
        }
        for (int i = 2; i <= 46340; i++) {
            if (i * i > num) {
                break;
            }
            if (i * i == num) {
                return true;
            }
        }
        return false;
    }
}

到了這里,關(guān)于代碼隨想錄 LeetCode數(shù)組篇 二分查找的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【代碼隨想錄算法第一天| 704.二分查找 27.移除元素】

    題目鏈接:二分查找 文章講解:代碼隨想錄.二分查找 視頻講解:手把手帶你撕出正確的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_嗶哩嗶哩_bilibili 二分前提:有序數(shù)組,數(shù)組中無重復(fù)元素 方法:結(jié)合數(shù)組的特征,可以為左閉右閉區(qū)間[0, 數(shù)組長度-1],或者左

    2024年02月16日
    瀏覽(21)
  • 【代碼隨想錄 | Leetcode | 第四天】數(shù)組 | 螺旋矩陣 | 59

    【代碼隨想錄 | Leetcode | 第四天】數(shù)組 | 螺旋矩陣 | 59

    歡迎來到小K的Leetcode|代碼隨想錄|專題化專欄,今天將為大家?guī)砺菪仃嚨姆窒?? 給你一個(gè)正整數(shù) n ,生成一個(gè)包含 1 到 n 2 所有元素,且元素按順時(shí)針順序螺旋排列的 n x n 正方形矩陣 matrix 。 示例 1: 示例 2: 提示: 思路: 本類型題目其實(shí)都不涉及什么算法,就是模擬

    2024年02月16日
    瀏覽(23)
  • 【代碼隨想錄 | Leetcode | 第四天】數(shù)組 | 螺旋矩陣 | 59-54

    【代碼隨想錄 | Leetcode | 第四天】數(shù)組 | 螺旋矩陣 | 59-54

    歡迎來到小K的Leetcode|代碼隨想錄|專題化專欄,今天將為大家?guī)砺菪仃嚨姆窒?? 給你一個(gè)正整數(shù) n ,生成一個(gè)包含 1 到 n 2 所有元素,且元素按順時(shí)針順序螺旋排列的 n x n 正方形矩陣 matrix 。 示例 1: 示例 2: 提示: 思路: 本類型題目其實(shí)都不涉及什么算法,就是模擬

    2024年02月16日
    瀏覽(25)
  • 代碼隨想錄Day1 | 數(shù)組01- leetcode 704、27

    題目鏈接:二分查找 關(guān)鍵問題: ????????- 邊界(left、right)、當(dāng)前查找值(middle) ? ? ? ? ? ? ? ? - target大于當(dāng)前查找值 -- 當(dāng)前查找區(qū)域的右邊,更改區(qū)間left ? ? ? ? ? ? ? ? - target小于當(dāng)前查找值 -- 當(dāng)前查找區(qū)域的左邊,更改區(qū)間right ? ? ? ? ? ? ? ? - middle的計(jì)

    2024年02月16日
    瀏覽(88)
  • 【代碼隨想錄-Leetcode第六題:209. 長度最小的子數(shù)組】

    【代碼隨想錄-Leetcode第六題:209. 長度最小的子數(shù)組】

    給定一個(gè)含有 n 個(gè)正整數(shù)的數(shù)組和一個(gè)正整數(shù) target 。 找出該數(shù)組中滿足其和 ≥ target 的長度最小的 連續(xù)子數(shù)組 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其長度。如果不存在符合條件的子數(shù)組,返回 0 。 參考【代碼隨想錄】 示例 1: 示例 3: 提示: 1 = target = 109 1 = nums.length

    2024年02月12日
    瀏覽(26)
  • 代碼隨想錄第6天| 哈希表理論基礎(chǔ) ,LeetCode242.有效的字母異位詞,LeetCode349. 兩個(gè)數(shù)組的交集,LeetCode202. 快樂數(shù),LeetCode1. 兩數(shù)之和

    代碼隨想錄第6天| 哈希表理論基礎(chǔ) ,LeetCode242.有效的字母異位詞,LeetCode349. 兩個(gè)數(shù)組的交集,LeetCode202. 快樂數(shù),LeetCode1. 兩數(shù)之和

    哈希表(散列表)理論基礎(chǔ) : 哈希表是根據(jù)關(guān)鍵碼的值而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)。 直白來講其實(shí)數(shù)組就是一張哈希表。 ? 什么時(shí)候想到用哈希法, 當(dāng)我們遇到了要快速判斷一個(gè)元素是否出現(xiàn)集合里的時(shí)候,就要考慮哈希法 。 當(dāng)我們遇到了要快速判斷一個(gè)元素是否出現(xiàn)集

    2024年02月10日
    瀏覽(90)
  • 代碼隨想錄Leetcode70. 爬樓梯

    代碼隨想錄Leetcode70. 爬樓梯

    ? ? ? ? 空間復(fù)雜度為O(N),如果想要優(yōu)化空間復(fù)雜度,則只用三個(gè)變量進(jìn)行狀態(tài)轉(zhuǎn)移也可以,參考 代碼隨想錄 Leetcode509. 斐波那契數(shù)-CSDN博客

    2024年02月19日
    瀏覽(97)
  • 代碼隨想錄Leetcode 343. 整數(shù)拆分

    代碼隨想錄Leetcode 343. 整數(shù)拆分

    ? ? ? ? dp[i]表示i所能拆分的最大乘積,則dp[i] 與dp[i - 1]的遞推公式是: ? ? ? ? ? ? ? ? max( 1~n * dp[n ~ 1])

    2024年02月21日
    瀏覽(101)
  • 代碼隨想錄 Leetcode763. 劃分字母區(qū)間
  • 代碼隨想錄 Leetcode18. 四數(shù)之和

    代碼隨想錄 Leetcode18. 四數(shù)之和

    ? ? ? ? 不行了,今天做了太多n數(shù)之和要吐了,太惡心了,一堆剪枝,去重太惡心人了。最后還是照著卡哥的改

    2024年01月17日
    瀏覽(97)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包