1. 程式人生 > 其它 >ARTS Week 30

ARTS Week 30

Algorithm

本週的 LeetCode 題目為 162. 尋找峰值

峰值元素是指其值嚴格大於左右相鄰值的元素。

給你一個整數陣列 nums,找到峰值元素並返回其索引。陣列可能包含多個峰值,在這種情況下,返回 任何一個峰值 所在位置即可。

你可以假設 nums[-1] = nums[n] = -∞

你必須實現時間複雜度為 O(log n) 的演算法來解決此問題。

輸入:nums = [1,2,3,1]
輸出:2
解釋:3 是峰值元素,你的函式應該返回其索引 2。

因為題目要求演算法複雜度是 O(log n),那麼不能進行遍歷,則需要進行二分查詢。為了避免峰值元素在左右邊界上,那麼在原陣列左右邊界上分別增加一個負無窮數。接下來進行二分查詢,判斷mid是否符合題目要求,若符合則更新結果,接下來分別尋找 left ~ mid

mid ~ right 範圍中符合條件的數,如找到的數大於之前找到的結果,則更新結果。

class Solution {
    public int findPeakElement(int[] nums) {
        if (nums.length == 1) {
            return 0;
        }
        if (nums.length == 2) {
            return nums[0] > nums[1]? 0: 1;
        }

        int length = nums.length;
        float[] arr = new float[length+2];
        arr[0] = Float.NEGATIVE_INFINITY;
        for (int i = 0; i < length; i++) {
            arr[i+1] = nums[i];
        }
        arr[length+1] = Float.NEGATIVE_INFINITY;

        int ans = binarySearchPeak(arr, 1, length) - 1;
        return ans;
    }

    public int binarySearchPeak(float[] arr, int left, int right) {
        if (left > right) {
            return 0;
        }
        if (left == right) {
            return left;
        }

        int mid = left + (right - left) / 2;
        int ans = 0;
        if (arr[mid] > arr[mid-1] && arr[mid] > arr[mid+1]) {
            ans = mid;
        }
        int leftAns = binarySearchPeak(arr, left, mid-1);
        int rightAns = binarySearchPeak(arr, mid+1, right);
        if (arr[ans] < arr[leftAns]) {
            ans = leftAns;
        } if (arr[ans] < arr[rightAns]) {
            ans = rightAns;
        }
        return ans;
    }
}

Review

本週 Review 的英文文章為:一切東西都必須支付兩次

作者的觀點乍聽起來很奇怪,我們買任何東西都是一次付費即可,為什麼要支付兩次呢?例如,花20元買了一本書,但是當你閱讀它時,可能需要花費10小時來閱讀它,這便是第二個價格;再比如手機、傢俱等、當你花錢購買它們後,還需要花時間來學習使用他們,這樣它們才能發揮其效果,這些都是第二價格。

作者認為這是我們現代生活的有時感到自欺欺人的原因之一,我們不斷地在支付著第一個價格,相應地也產生了鉅額的第二價格債務,但購買任何物品想要取得回報,需要兩個價格都被支付才行。在第二價格債務中,手機應用程式、流媒體服務和加工食品等,它們僅需要付出很少的努力便可享受他們,於是我們很容易沉迷於它們,但這並不能幫助我們成長。

作者想到的唯一解決辦法是避免支付不必要的第一價格,這樣你就不會新增第二價格的債務,你就會有時間來享受一本好書,學習一種樂器等。

弄清楚什麼是第二價格並不難,重要的是你可以堅持下去支付第二價格,慢慢地,獎勵將會在陌生的時刻出現。

Tip

C 語言中 sizeof 是在編譯時就計算得到結果,因此對於指標p來說,sizeof(p) 得到的是指標的大小,而 sizeof(*p) 得到的是指向型別的大小。示例如下:

#include <stdio.h>
 
int main()
{
    // printf("%d\n", sizeof(tmp1));
    // printf("%d\n", sizeof(p_tmp));
    // printf("%d\n", p_tmp[2].x);
    int a[10];
    int *p = a;
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(p) = %d\n", sizeof(p));
    printf("sizeof(*p) = %d\n", sizeof(*p));
}

執行結果是:

sizeof(a) = 40
sizeof(p) = 8
sizeof(*p) = 4

Share

隔離了在宿舍呆了一週(未來估計還要呆一段時間),最開始還不太適應在宿舍的生活,找不到狀態,效率比較低。未來需要逐步適應在宿舍的生活,找回原本的狀態。