徒手挖地球二四周目

徒手挖地球二四周目

NO.225 用隊列實現棧 簡單

3g45b4.png
思路一:使用隊列API 其實沒有太搞明白這個題目的意思。。。leetcode打卡活動第一天題目。

主要是push()方法每次將新加入元素x之前的元素都按序出隊並重新入隊,這樣新元素x就在隊頭。

然後pop()、top()、empty()直接調用隊列API就好。。。

public class MyStack {

    Queue<Integer> queue;
    /** Initialize your data structure here. */
    public MyStack() {
        this.queue=new LinkedList<>();
    }

    /** Push element x onto stack. */
    public void push(int x) {
        queue.add(x);
        for (int i = 1; i < queue.size(); i++) {
            queue.add(queue.remove());
        }
    }

    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue.poll();
    }

    /** Get the top element. */
    public int top() {
        return queue.peek();
    }

    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue.isEmpty();
    }
}

時間複雜度:push()是O(n),其餘三個方法時O(1)

NO.53 最大子序和 簡單

3g44rF.png
思路一:動態規劃法 分析dp那就要先分析dp[i]的含義:以第i元素結尾的最大序列和。

初始化:dp[0]以第0號元素結尾的序列只有nums[0]本身,所以dp[0]=nums[0]

轉移方程:dp[i]=Max(dp[i-1]+nums[i],nums[i]),因爲dp[i-1]是以i-1爲結尾的序列和中的最大值,所以我們想找nums[i]結尾的最大序列和只需要比較"前一個最大序列和+nums[i]“和"nums[i]”。舉個例子:
在這裏插入圖片描述

public int maxSubArray(int[] nums) {
    if (nums==null||nums.length==0)return 0;
    int[] dp=new int[nums.length];
    //初始化
    dp[0]=nums[0];
    //填寫dp數組同時用max記錄當前最大的序列和
    int max=dp[0];
    for (int i = 1; i < nums.length; i++) {
        dp[i]=Math.max(nums[i],dp[i-1]+nums[i]);
        max=Math.max(max,dp[i]);
    }
    return max;
}

經過思考不難發現,並不需要開闢一個數組來保存每一個子序和。每次填寫只需要關心上一次狀態值即可,且每個狀態值只需要使用一次。所以我們可以用一個int變量代替dp數組即可:

public int maxSubArray(int[] nums) {
    if (nums==null||nums.length==0)return 0;
    //初始化
    int dp=nums[0];
    //更新當前i結尾的最大序列和同時用max記錄最大的序列和
    int max=dp;
    for (int i = 1; i < nums.length; i++) {
        dp=Math.max(nums[i],dp+nums[i]);
        max=Math.max(max,dp);
    }
    return max;
}

時間複雜度:O(n)

NO.206 翻轉鏈表 簡單

3R4HGn.png
本題是K個一組翻轉鏈表這道題的其中一步,學習完本題可以趁熱打鐵學習NO.25,題解參考徒手挖地球十八週目

思路一:迭代實現 翻轉鏈表需要三個"指針":pre指向前驅、curr指向當前節點、next指向後繼。

過程比較簡單,自己模擬一遍就好了:
3R4b2q.png
3R47Ps.png

public ListNode reverseList(ListNode head) {
    if (head==null||head.next==null)return head;
    ListNode pre=null,curr=head;
    while (curr!= null) {
        ListNode next=curr.next;
        curr.next=pre;
        pre=curr;
        curr=next;
    }
    return pre;
}

時間複雜度:O(n)

思路二:遞歸實現 每層遞歸返回已經翻轉好的部分。

public ListNode reverseList(ListNode head) {
    if (head==null||head.next==null)return head;
    ListNode pre=reverseList(head.next);
    head.next.next=head;
    head.next=null;
    return pre;
}

時間複雜度:O(n)

NO.54 螺旋矩陣 中等

3R7fAO.png
思路一:按層模擬法 從[0][0]開始模擬順時針一層一層的遍歷所有元素。
在這裏插入圖片描述
計算層數count:(Min(row,col)+1)/2,因爲每次最多有兩行兩列組成,最少由一行或一列組成。

遍歷每一層curr即[0,count),每層有四次"轉彎":

  1. 每一層先從左到右遍歷一行,即for(i=curr;i<col-curr;i++)matrix[curr][i]
  2. 再從上到下遍歷一列,即for(i=curr+1;i<row-curr;i++)matrix[i][col-1-curr]
  3. 再從右到左遍歷一行,即for(i=col-1-curr-1;i>=curr;i--)matrix[row-1-i][i]
  4. 最後從下到上遍歷一列,即for(i=row-1-curr-1;i>=curr+1;i--)matrix[i][curr]

ps:每一層除了第一行是遍歷一整行元素,其餘三部分都需要注意不要重複遍歷"拐點"元素。

上述是常規層(兩行兩列)的遍歷;如果只有一行,從右向左遍歷時會重複遍歷;如果只有一列,從下向上遍歷時會重複遍歷,如何解決這個問題?

答:只有一行或只有一列時,不進行右向左或下向上的遍歷即可。如何判斷?row-1-curr==curr說明當前層只有一行;col-1-curr==curr說明當前層只有一列。

public List<Integer> spiralOrder(int[][] matrix) {
    List<Integer> res=new ArrayList<>();
    if (matrix==null||matrix.length==0)return res;
    int row = matrix.length,col=matrix[0].length;
    //計算有多少層
    int count=(Math.min(row,col)+1)/2;
    //當前層
    int curr=0;
    //遍歷每一層
    for (;curr<count;curr++){
        //從左向右
        for (int i = curr; i < col - curr; i++) {
            res.add(matrix[curr][i]);
        }
        //從上到下
        for (int i = curr+1; i < row-curr; i++) {
            res.add(matrix[i][col-1-curr]);
        }
        //從右到左
        for (int i = col-1-curr-1; i >= curr&&(row-1-curr!=curr); i--) {
            res.add(matrix[row-1-curr][i]);
        }
        //從下到上
        for (int i = row-1-curr-1; i >= curr+1&&(col-1-curr!=curr); i--) {
            res.add(matrix[i][curr]);
        }
    }
    return res;
}

時間複雜度:O(n)


本人菜鳥,有錯誤請告知,感激不盡!

更多題解和學習記錄博客:博客github

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