7月5日的五題leetcode

63. 不同路徑 II

64. 最小路徑和

66. 加一

68. 文本左右對齊

69. x 的平方根

------------------------------分割線-----------------------------------

63. 不同路徑 II

Difficulty: 中等

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記爲“Start” )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記爲“Finish”)。

現在考慮網格中有障礙物。那麼從左上角到右下角將會有多少條不同的路徑?

網格中的障礙物和空位置分別用 10 來表示。

說明:mn 的值均不超過 100。

示例 1:

輸入:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
輸出: 2
解釋:
3x3 網格的正中間有一個障礙物。
從左上角到右下角一共有 2 條不同的路徑:
1\. 向右 -> 向右 -> 向下 -> 向下
2\. 向下 -> 向下 -> 向右 -> 向右

Solution:動態規劃

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m, n;
        m = obstacleGrid.length;
        if(m == 0) return 0;
        n = obstacleGrid[0].length;
        if(n == 0) return 0;

        int[][] dp = new int[m][n];
        if(obstacleGrid[0][0] == 1) return 0;
        dp[0][0] = 1;

        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                if(obstacleGrid[i][j] == 1) dp[i][j] = 0;  //遇到障礙物,直接爲0
                else if(i==0 && j==0) continue;
                else if(i==0){
                    dp[i][j] = dp[i][j-1];
                }
                else if(j == 0){
                    dp[i][j] = dp[i-1][j];
                }
                else{
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
                }
            }
        }
        return dp[m-1][n-1];
    }
}

64. 最小路徑和

Difficulty: 中等

給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和爲最小。

**說明:**每次只能向下或者向右移動一步。

示例:

輸入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
輸出: 7
解釋: 因爲路徑 1→3→1→1→1 的總和最小。

Solution:動態規劃

class Solution {
    public int minPathSum(int[][] grid) {
        int m, n;
        m = grid.length;
        if(m<=0) return 0;
        n = grid[0].length;
        if(n<=0) return 0;

        int[][] dp = new int[m][n];
        dp[0][0] = grid[0][0];

        for(int i=0; i<m; i++){
            for(int j=0; j<n; j++){
                if(i==0 && j==0) continue;
                else if(i==0) dp[i][j] = grid[i][j]+dp[i][j-1];
                else if(j==0) dp[i][j] = grid[i][j]+dp[i-1][j];
                else{
                    dp[i][j] = grid[i][j] + Math.min(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        return dp[m-1][n-1];
    }
}

66. 加一

Difficulty: 簡單

給定一個由整數組成的非空數組所表示的非負整數,在該數的基礎上加一。

最高位數字存放在數組的首位, 數組中每個元素只存儲單個數字。

你可以假設除了整數 0 之外,這個整數不會以零開頭。

示例 1:

輸入: [1,2,3]
輸出: [1,2,4]
解釋: 輸入數組表示數字 123。

示例 2:

輸入: [4,3,2,1]
輸出: [4,3,2,2]
解釋: 輸入數組表示數字 4321。

Solution:看1這個數字,到底加在那個位置

//這個1到底應該加在哪裏
class Solution {
    public int[] plusOne(int[] digits) {
        for(int i=digits.length-1; i>=0; i--){
            if(digits[i] != 9){         //不是9,直接加,然後返回
                digits[i] = digits[i]+1;
                return digits;  
            }
            else digits[i] = 0;
        }

        int[] res = new int[digits.length+1];
        res[0] = 1;
        for(int i=1; i<res.length; i++){
            res[i] = 0;
        }
        return res;
    }
}

68. 文本左右對齊

Difficulty: 困難

給定一個單詞數組和一個長度 maxWidth,重新排版單詞,使其成爲每行恰好有 maxWidth 個字符,且左右兩端對齊的文本。

你應該使用“貪心算法”來放置給定的單詞;也就是說,儘可能多地往每行中放置單詞。必要時可用空格 ' ' 填充,使得每行恰好有 maxWidth 個字符。

要求儘可能均勻分配單詞間的空格數量。如果某一行單詞間的空格不能均勻分配,則左側放置的空格數要多於右側的空格數。

文本的最後一行應爲左對齊,且單詞之間不插入額外的空格。

說明:

  • 單詞是指由非空格字符組成的字符序列。
  • 每個單詞的長度大於 0,小於等於 maxWidth
  • 輸入單詞數組 words 至少包含一個單詞。

示例:

輸入:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
輸出:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]

示例 2:

輸入:
words = ["What","must","be","acknowledgment","shall","be"]
maxWidth = 16
輸出:
[
  "What   must   be",
  "acknowledgment  ",
  "shall be        "
]
解釋: 注意最後一行的格式應爲 "shall be    " 而不是 "shall     be",
     因爲最後一行應爲左對齊,而不是左右兩端對齊。       
     第二行同樣爲左對齊,這是因爲這行只包含一個單詞。

示例 3:

輸入:
words = ["Science","is","what","we","understand","well","enough","to","explain",
         "to","a","computer.","Art","is","everything","else","we","do"]
maxWidth = 20
輸出:
[
  "Science  is  what we",
  "understand      well",
  "enough to explain to",
  "a  computer.  Art is",
  "everything  else  we",
  "do                  "
]

Solution:兩個問題:1.每行需要放置多少的單詞 2.每行的空格應該怎麼放

import java.util.ArrayList;
import java.util.List;

//兩個問題:1.每行需要放置多少的單詞 2.每行的空格應該怎麼放
class Solution {
    public List<String> fullJustify(String[] words, int maxWidth) {
        List<String> res = new ArrayList<>();
        List<String> temp = new ArrayList<>();
        StringBuilder str;
        int count = 0;
        for(int i=0; i<words.length; i++){
            //可以繼續添加
            if(count+words[i].length() <= maxWidth){
                temp.add(words[i]);
                count += words[i].length();
                count++; //一個單詞後面一個空格
            }
            //不能再添加
            else{
                int wordNum = count-temp.size();
                int blackNum = maxWidth-wordNum; //空格的個數
                str =  new StringBuilder();
                
                //只有一個元素,左對齊
                if(temp.size() == 1){
                    str.append(temp.get(0));
                    for(int j=0; j<maxWidth-temp.get(0).length(); j++){
                        str.append(" ");
                    }
                }
                //左右對齊
                else if(temp.size() > 1){
                    int x = blackNum/(temp.size()-1);
                    int y = blackNum%(temp.size()-1); //添加空格
                    for(int j=0; j<temp.size()-1; j++){
                        str.append(temp.get(j));
                        for(int p=0; p<x; p++){
                            str.append(" ");
                        }
                        if(y != 0){
                            str.append(" ");
                            y--;
                        }
                    }
                    str.append(temp.get(temp.size()-1)); //最後一個元素後面不加空格
                }

                //System.out.println("2str:"+str);
                res.add(str.toString());

                temp = new ArrayList<>();
                temp.add(words[i]);
                count = words[i].length() +1;
                //System.out.println("count:"+count);
            }
        }
        
        if(temp.size() > 0){   //最後一行
            str = new StringBuilder();
            for(int j=0; j<temp.size()-1; j++){
                str.append(temp.get(j)+" ");
            }
            str.append(temp.get(temp.size()-1));
            for(int j=0; j<maxWidth-count+1; j++){
                str.append(" ");
            }
            //System.out.println("3str:"+str);
            res.add(str.toString());
        }
        return res;
    }
}

69. x 的平方根

Difficulty: 簡單

實現 int sqrt(int x) 函數。

計算並返回 x 的平方根,其中 x 是非負整數。

由於返回類型是整數,結果只保留整數的部分,小數部分將被捨去。

示例 1:

輸入: 4
輸出: 2

示例 2:

輸入: 8
輸出: 2
說明: 8 的平方根是 2.82842..., 
     由於返回類型是整數,小數部分將被捨去。

Solution:二分法,注意越界

class Solution {
    public int mySqrt(int x) {
        if(x == 0 || x == 1) return x;
        int low = 0, high = x;
        while(low <= high){
            long mid = (high-low)/2 + low;   // mid容易越界
            if(mid*mid > x){
                if((mid-1)*(mid-1) < x) return (int)mid-1;
                else high = (int)mid-1;
            }
            else if(mid*mid == x){
                return (int)mid;
            }
            else{
                if((mid+1)*(mid+1) > x) return (int)mid;
                else low = (int)mid+1;
            }

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