[LeetCode] 劍指offer算法題記錄 持續更新ing

劍指offer

時隔一年重新開始劍指offer,爭取月底之前做完劍指吧,做個小記錄。

Easy

  • 03 數組中的重複數字

可以用HashMap,比較簡單,在評論區看到一種比較好的辦法,記錄一下

public int findRepeatNumber(int[] nums) {
        int n = nums.length;
        for (int i = 0;i < n;i ++){
            int cur = nums[i];
            if(cur < 0){
                cur = cur + n;
            }
            if(nums[cur]<0){
                return cur;
            }
            nums[i] = nums[i] - n;
        }
        return -1;
    }
  • 05 替換空格
    public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()){
            if(c==' ') {
                sb.append("%20");
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
  • 06 從尾到頭打印鏈表

用棧就行了

    public int[] reversePrint(ListNode head) {
        Stack<ListNode> stack = new Stack<>();
        int count = 0;
        while (head!=null) {
            stack.push(head);
            head = head.next;
            count++;
        }
        int[] result = new int[count];
        count = 0;
        while (!stack.isEmpty()) {
            result[count++] = stack.pop().val;
        }
        return result;

    }
  • 09 用兩個棧實現隊列
class CQueue {

    /**
     * 前
     * */
    private Stack<Integer> s1;
    /**
     * 後
     * */
    private Stack<Integer> s2;
    public CQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }

    public void appendTail(int value) {
        s2.push(value);
    }

    public int deleteHead() {
        if (!s1.isEmpty()){
            return s1.pop();
        }
        while(!s2.isEmpty())
        {
            s1.push(s2.pop());
        }
        return s1.isEmpty()?-1:s1.pop();
    }
}

  • 10 斐波拉契

簡單dp

    public static int fib(int n) {
        if(n<=1)
        {
            return n;
        }
        int[] nums = new int[n+1];
        nums[0] = 0;
        nums[1] = 1;
        for (int i = 2;i <= n;i++)
        {
            nums[i] = nums[i-1]+nums[i-2];
        }
        return nums[n];
    }
  • 11 青蛙跳臺階

和上面類似

    public static int numWays(int n) {
        if(n==0||n==1)
        {
            return 1;
        }
        int[] v = new int[n+1];
        v[0] = 1;
        v[1] = 1;
        v[2] = 2;

        for (int i = 3;i <= n ;i++)
        {
            v[i] = (v[i-1]+v[i-2])%(1000000007);
        }
        return v[n];
    }
  • 11 旋轉數組的最小數字

轉爲二分查找比較合適,但是需要變通一下。

    public static int minArray(int[] numbers) {
        int left = 0;
        int right = numbers.length-1;
        int mid;
        if(numbers[left]<numbers[right])
        {
            return numbers[left];
        }
        while (left<right)
        {
            if(numbers[left]<numbers[right])
            {
                return numbers[left];
            }
            mid = left + (right - left) / 2;
            if(numbers[mid] < numbers[right])
            {
                right = mid;
            }
            else if(numbers[mid] > numbers[right])
            {
                left = mid + 1;
            }
            else
            {
                right--;
            }
        }
        return numbers[left];
    }
  • 15 二進制中1的個數

第一種辦法,比較容易想到,模擬我們手動求數字二進制形式的過程即可,不斷取2的模,然後計數,但需要注意的是,這裏n是無符號數,最高位不做符號位,而是數字位,那麼符號右移的時候,需要採用java的>>>來進行運算,因爲對於有符號的右移,n爲負數的時候,最高位會補1,反之補0,但這裏n是無符號數,所以這裏只能採取無符號右移,也就是默認補0,此外,對於循環的終止條件,不應該用n>0,因爲n可能爲負數。

    public int hammingWeight(int n) {
        int count = 0;
        int num = n;
        while (num != 0 ){
            int t = num & 1;
            count = count + t;
            num = num >>> 1;
        }
        return count;

    }

第二種辦法比較巧,相比於第一種辦法突出的地方在於,循環次數減少,因爲這裏我們只需要計算1的個數,而其餘位數的0我們並不在乎,所以可以用n&(n-1)來消去最右邊的1,這樣循環次數就變成了1的個數。

    public static int hammingWeight(int n) {
        int count = 0;
        int num = n;
        while (num != 0 ){
            int t = num & 1;
            count = count + t;
            num = num >>> 1;
        }
        return count;
    }

Mid用連

Hard

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章