1. 程式人生 > >【LeetCode】Day 4

【LeetCode】Day 4

文章目錄

500. Keyboard Row

Given a List of words, return the words that can be typed using letters of alphabet on only one row’s of American keyboard like the image below.
在這裡插入圖片描述
Example:

Input: [“Hello”, “Alaska”, “Dad”, “Peace”]
Output: [“Alaska”, “Dad”]

題意:
如果一個單詞中每個字母都屬於鍵盤的同一行,則輸出。

	
   

    public String[] findWords(String[] words) {
        List<String> list = new ArrayList<>(words.length);
        for (String word : words) {
            if (is2(word)) {
                list.add(word);
            }
        }
        return list.
toArray(new String[0]); } //方法1 String[] ss = { "qwertyuiop", "asdfghjkl", "zxcvbnm" }; //O(m * n) boolean is(String word) { for (String s : ss) { if (s.indexOf((char) (word.charAt(0) | 32)) != -1) {// OR 32(0x20) toLowerCase for (int i = 1; i < word.length(); i++) { if (s.indexOf((char) (word.charAt(i) | 32)) == -1) { return false; } } return true; } } return false; } //方法2 //0代表屬於第一排,1第二排,2第三排字母 int[] ii = {1, 2, 2, 1, 0, 1, 1, 1, 0, 1, 1, 1, 2, 2, 0, 0, 0, 0, 1, 0, 0, 2, 0, 2, 0, 2}; //O(n) boolean is2(String word) { //得到第一個屬於哪一行,後面的必須和他同一行,才能返回true char c0 = word.charAt(0); int r = ii[(c0 | 32) - 'a'];// OR 32(0x20) toLowerCase for (int i = 1; i < word.length(); i++) { if (ii[(word.charAt(i) | 32) - 'a'] != r) { return false; } } return true; }

872. Leaf-Similar Trees

Consider all the leaves of a binary tree. From left to right order, the values of those leaves form a leaf value sequence.

在這裡插入圖片描述
For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8).

Two binary trees are considered leaf-similar if their leaf value sequence is the same.

Return true if and only if the two given trees with head nodes root1 and root2 are leaf-similar.

題意:
判斷兩顆二叉樹葉子節點序列是否相同(如圖葉子節點為[6,7,4,9,8])

    public boolean leafSimilar(TreeNode root1, TreeNode root2) {
        List<Integer> l1 = new ArrayList<>();
        List<Integer> l2 = new ArrayList<>();
        getLeaf(root1, l1);
        getLeaf(root2, l2);
        if(l1.size() != l2.size()) return false;
        for(int i = 0; i < l1.size(); i++){
            if(l1.get(i) != l2.get(i))return false;
        }
        return true;
    }
    //遞迴獲取樹節點,新增到List中
    void getLeaf(TreeNode node, List<Integer> list) {
        if (node != null) {
            if(node.left == null && node.right == null) {
                list.add(node.val);//如果左右節點都為null,說明當前節點為葉子節點,新增到List中
            }else{//否則,遞迴尋找葉子節點
                getLeaf(node.left, list);
                getLeaf(node.right, list);
            }
        }
    }

893. Groups of Special-Equivalent Strings

You are given an array A of strings.

Two strings S and T are special-equivalent if after any number of moves, S == T.

A move consists of choosing two indices i and j with i % 2 == j % 2, and swapping S[i] with S[j].

Now, a group of special-equivalent strings from A is a non-empty subset S of A such that any string not in S is not special-equivalent with any string in S.

Return the number of groups of special-equivalent strings from A.
Example 1:

Input: [“a”,“b”,“c”,“a”,“c”,“c”]
Output: 3
Explanation: 3 groups [“a”,“a”], [“b”], [“c”,“c”,“c”]
Example 2:

Input: [“aa”,“bb”,“ab”,“ba”]
Output: 4
Explanation: 4 groups [“aa”], [“bb”], [“ab”], [“ba”]
Example 3:

Input: [“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
Output: 3
Explanation: 3 groups [“abc”,“cba”], [“acb”,“bca”], [“bac”,“cab”]
Example 4:

Input: [“abcd”,“cdab”,“adcb”,“cbad”]
Output: 1
Explanation: 1 group [“abcd”,“cdab”,“adcb”,“cbad”]

題意:
沒讀懂題目,待續…

766. Toeplitz Matrix

Toeplitz Matrix 是一種 左上 到 右下 連線的元素相等 的矩陣
Example:

Input:
matrix = [
[1,2,3,4],
[5,1,2,3],
[9,5,1,2]
]
Output: True
Explanation:
In the above grid, the diagonals are:
“[9]”, “[5, 5]”, “[1, 1, 1]”, “[2, 2, 2]”, “[3, 3]”, “[4]”.
In each diagonal all elements are the same, so the answer is True.

matrix[i][j] 和 matrix[i + 1][j + 1] 進行比較,如果有一個不相等,返回false

    public boolean isToeplitzMatrix(int[][] matrix) {
        int rowLen = matrix.length;
        int colLen = matrix[0].length;
        for (int i = 0; i < rowLen - 1; i++) {
            for (int j = 0; j < colLen - 1; j++) {
                if(matrix[i][j] != matrix[i + 1][j + 1]) {
                    return false;
                }
            }
        }   
        return true;
    }

884. Uncommon Words from Two Sentences

找出兩個句子中不重複且不同的單詞
We are given two sentences A and B. (A sentence is a string of space separated words. Each word consists only of lowercase letters.)
A word is uncommon if it appears exactly once in one of the sentences, and does not appear in the other sentence.
Return a list of all uncommon words.
You may return the list in any order.

Example:

Input: A = “this apple is sweet”, B = “this apple is sour”
Output: [“sweet”,“sour”]

Input: A = “apple apple”, B = “banana”
Output: [“banana”]
直接用Map吧元素都裝進去,遍歷出個數為一的元素

    public String[] uncommonFromSentences(String A, String B) {
        String[] AA = A.split(" ");
        String[] BB = B.split(" ");
        Map<String,Integer> map = new HashMap<>();
        for(String a: AA) {
            map.put(a, map.getOrDefault(a, 0) + 1);
        }
        for(String b: BB) {
            map.put(b, map.getOrDefault(b, 0) + 1);
        }
        List<String> list = new ArrayList<>();

        for(Map.Entry<String, Integer> entry: map.entrySet()){
            if (entry.getValue() == 1) list.add(entry.getKey());
        }
        return list.toArray(new String[0]);
    }

897. Increasing Order Search Tree

Given a tree, rearrange the tree in in-order so that the leftmost node in the tree is now the root of the tree, and every node has no left child and only 1 right child.

Example 1:
Input: [5,3,6,2,4,null,8,1,null,null,null,7,9]

       5
      / \
    3    6
   / \    \
  2   4    8
 /        / \ 
1        7   9

Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]

 1
  \
   2
    \
     3
      \
       4
        \
         5
          \
           6
            \
             7
              \
               8
                \
                 9  

中序遍歷 每個節點的值 新增到樹節點的右子節點


    private TreeNode result = new TreeNode(-1);
    private TreeNode head = result;

    public TreeNode increasingBST(TreeNode root) {
        helper(root);
        return head.right;
    }

    private void helper(TreeNode root) {
        if (root != null) {
            helper(root.left);
            
            result.right = new TreeNode(root.val);
            result = result.right;
            
            helper(root.right);
        }
    }

463. Island Perimeter

you are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water.

Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells).

The island doesn’t have “lakes” (water inside that isn’t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don’t exceed 100. Determine the perimeter of the island.

Input:
[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]
Output: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:
在這裡插入圖片描述

求周長

	//暴力解,每個格子邊長為4,上下左右每有一個相鄰就-1
    public int islandPerimeter(int[][] grid) {
        int s = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if (grid[i][j] == 1) {
                    s += 4;
                    if (j < grid[i].length - 1 && grid[i][j + 1] == 1) {
                        s--;
                    }
                    if (i < grid.length - 1 && grid[i + 1][j] == 1) {
                        s--;
                    }
                    if (j > 0 && grid[i][j - 1] == 1) {
                        s--;
                    }
                    if (i > 0 && grid[i - 1][j] == 1) {
                       s--;
                    }
                }
            }
        }
        return s;
    }
    //仔細觀察周長,格子數,鄰居數的關係,發現 周長 = 4倍格子數 - 2倍相鄰數
    public int islandPerimeter(int[][] grid) {
        if(grid == null || grid.length == 0 || grid[0].length == 0) return 0;
        int s = 0, n = 0;
        int row = grid.length;
        int col = grid[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == 1) {
                    s++;//數出格子的數量
                    if(j < col - 1 && grid[i][j + 1] == 1) {
                        n++;//相鄰+1
                    }
                    if(i < row - 1 && grid[i+1][j] == 1) {
                        n++;//相鄰+1
                    }
                }
            }
        }
        return 4 * s - 2 * n;
    }
    //把上面的化簡一下,每次直接遇到格子+4,遇到相鄰的-2
    public int islandPerimeter(int[][] grid) {
        if(grid == null || grid.length == 0 || grid[0].length == 0) return 0;
        int s = 0;
        int row = grid.length;
        int col = grid[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == 1) {
                    s += 4;
                    if(j < col - 1 && grid[i][j + 1] == 1) {
                        s -= 2;
                    }
                    if(i < row - 1 && grid[i+1][j] == 1) {
                        s -= 2;
                    }
                }
            }
        }
        return s;
    }

682. Baseball Game

You’re now a baseball game point recorder.

Given a list of strings, each string can be one of the 4 following types:

Integer (one round’s score): Directly represents the number of points you get in this round.
“+” (one round’s score): Represents that the points you get in this round are the sum of the last two valid round’s points.
“D” (one round’s score): Represents that the points you get in this round are the doubled data of the last valid round’s points.
“C” (an operation, which isn’t a round’s score): Represents the last valid round’s points you get were invalid and should be removed.
Each round’s operation is permanent and could have an impact on the round before and the round after.

You need to return the sum of the points you could get in all the rounds.

Input: [“5”,“2”,“C”,“D”,"+"]
Output: 30
Explanation:
Round 1: You could get 5 points. The sum is: 5.
Round 2: You could get 2 points. The sum is: 7.
Operation 1: The round 2’s data was invalid. The sum is: 5.
Round 3: You could get 10 points (the round 2’s data has been removed). The sum is: 15.
Round 4: You could get 5 + 10 = 15 points. The sum is: 30.

Input: [“5”,"-2",“4”,“C”,“D”,“9”,"+","+"]
Output: 27
Explanation:
Round 1: You could get 5 points. The sum is: 5.
Round 2: You could get -2 points. The sum is: 3.
Round 3: You could get 4 points. The sum is: 7.
Operation 1: The round 3’s data is invalid. The sum is: 3.
Round 4: You could get -4 points (the round 3’s data has been removed). The sum is: -1.
Round 5: You could get 9 points. The sum is: 8.
Round 6: You could get -4 + 9 = 5 points. The sum is 13.
Round 7: You could get 9 + 5 = 14 points. The sum is 27.

    public int calPoints(String[] ops) {
        int sum = 0, v = 0, len = ops.length;
        int[] valid = new int[len];//儲存有效數字
        for(int i = 0, k = 0; i < len; i++){
            switch (ops[i]) {
            	//如果是"+", sum加上前兩個有效數字之和,然後把有效數字之和作為最新的一個有效數字
                case "+": v = valid[k - 2] + valid[k - 1];sum += v; valid[k++] = v; break;
                //如果是"C", sum減去上一個有效數字,並移除
                case "C": sum -= valid[--k]; break;
                //如果是"D", sum加上上一個有效數字的兩倍,然後把這個兩倍數作為最新的有效數字
                case "D": v = valid[k - 1] * 2; sum += v; valid[k++] = v; break;
                //如果是數字, 直接加到sum裡和有效數字中
                default : v = Integer.parseInt(ops[i]); sum += v; valid[k++] = v;
            }
        }
        return sum;
    }

669. Trim a Binary Search Tree

二叉樹剪枝
Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that all its elements lies in [L, R] (R >= L). You might need to change the root of the tree, so the result should return the new root of the trimmed binary search tree.

Example1:

Input: 
    1
   / \
  0   2

  L = 1
  R = 2

Output: 
    1
      \
       2

Example2:

Input: 
    3
   / \
  0   4
   \
    2
   /
  1

  L = 1
  R = 3

Output: 
      3
     / 
   2   
  /
 1
    public TreeNode trimBST(TreeNode root, int L, int R) {
        if (root != null) {
        	//如果當前節點小於左邊界,即[root,...,L,...,R,...],只需要剪右邊的子樹,扔掉左邊
            if (root.val < L) return trimBST(root.right, L, R);    
            //如果當前節點大於右邊界,即[...,L,...,R,...,root],只需要剪左邊的子樹,扔掉右邊
            if(root.val > R) return trimBST(root.left, L, R);  
            //新樹的左子樹為原左子樹裁剪後得到的新樹
            root.left = trimBST(root.left