Data Structure and Algorithm - Day 08

  • Greedy

    best in present

    The difference between Greedy and Dynamic Programming is that it makes choices on the solutions of each sub-problem and can't rollback.

    Dynamic Programming saves the previous operation results, and selects the current according to the previous results, and has the function of rollback.

  • 455. Assign Cookies

    Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie.

    Each child i has a greed factor g[i], which is the minimum size of a cookie that the child will be content with; and each cookie j has a size s[j]. If s[j] >= g[i], we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.

    Example 1:

    Input: g = [1,2,3], s = [1,1]
    Output: 1
    Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. 
    And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.
    You need to output 1.
    

    Example 2:

    Input: g = [1,2], s = [1,2,3]
    Output: 2
    Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. 
    You have 3 cookies and their sizes are big enough to gratify all of the children, 
    You need to output 2.
    

    Constraints:

    • 1 <= g.length <= 3 * 104
    • 0 <= s.length <= 3 * 104
    • 1 <= g[i], s[j] <= 231 - 1
    class Solution {
        public int findContentChildren(int[] g, int[] s) {
            int res = 0;
            Arrays.sort(g);
            Arrays.sort(s);
            for (int i = 0, j = 0; i < g.length && j < s.length; j++) {
                if (g[i] <= s[j]) {
                    res++;
                    i++;
                } 
            }
            return res;
        }
    }
    
  • 122. Best Time to Buy and Sell Stock II

    You are given an array prices where prices[i] is the price of a given stock on the ith day.

    Find the maximum profit you can achieve. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).

    Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).

    Example 1:

    Input: prices = [7,1,5,3,6,4]
    Output: 7
    Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
    Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
    

    Example 2:

    Input: prices = [1,2,3,4,5]
    Output: 4
    Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
    Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again.
    

    Example 3:

    Input: prices = [7,6,4,3,1]
    Output: 0
    Explanation: In this case, no transaction is done, i.e., max profit = 0.
    

    Constraints:

    • 1 <= prices.length <= 3 * 104
    • 0 <= prices[i] <= 104
    class Solution {
        public int maxProfit(int[] prices) {
            int res = 0;
            for (int i = 1; i < prices.length; i++) {
                res += Math.max(0, prices[i] - prices[i - 1]);
            }
            return res;
        }
    }
    
  • 55. Jump Game

    Given an array of non-negative integers nums, you are initially positioned at the first index of the array.

    Each element in the array represents your maximum jump length at that position.

    Determine if you are able to reach the last index.

    Example 1:

    Input: nums = [2,3,1,1,4]
    Output: true
    Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
    

    Example 2:

    Input: nums = [3,2,1,0,4]
    Output: false
    Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
    

    Constraints:

    • 1 <= nums.length <= 3 * 104
    • 0 <= nums[i] <= 105
    class Solution {
        public boolean canJump(int[] nums) {
            int end = nums.length - 1;
            for (int i = end; i >= 0; i--) {
                if (nums[i] + i >= end) {
                    end = i;
                }
            }
            return end == 0;
        }
    }
    
  • 45. Jump Game II

    Given an array of non-negative integers nums, you are initially positioned at the first index of the array.

    Each element in the array represents your maximum jump length at that position.

    Your goal is to reach the last index in the minimum number of jumps.

    You can assume that you can always reach the last index.

    Example 1:

    Input: nums = [2,3,1,1,4]
    Output: 2
    Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
    

    Example 2:

    Input: nums = [2,3,0,1,4]
    Output: 2
    

    Constraints:

    • 1 <= nums.length <= 1000
    • 0 <= nums[i] <= 105
    class Solution {
        public int jump(int[] nums) {
            if (nums.length < 2) return 0;
            int bound = 0;
            int time = 0;
            int end = 0;
            for (int i = 0; i < nums.length; ) {
                time++;
                for (int j = i; j <= bound; j++) {
                    end = Math.max(end, j + nums[j]);
                }
                if (end >= nums.length - 1) break;
                i = bound + 1;
                bound = end;
            }
            return time;
        }
    }
    
  • 860. Lemonade Change

    At a lemonade stand, each lemonade costs $5.

    Customers are standing in a queue to buy from you, and order one at a time (in the order specified by bills).

    Each customer will only buy one lemonade and pay with either a $5, $10, or $20 bill. You must provide the correct change to each customer, so that the net transaction is that the customer pays $5.

    Note that you don't have any change in hand at first.

    Return true if and only if you can provide every customer with correct change.

    Example 1:

    Input: [5,5,5,10,20]
    Output: true
    Explanation: 
    From the first 3 customers, we collect three $5 bills in order.
    From the fourth customer, we collect a $10 bill and give back a $5.
    From the fifth customer, we give a $10 bill and a $5 bill.
    Since all customers got correct change, we output true.
    

    Example 2:

    Input: [5,5,10]
    Output: true
    

    Example 3:

    Input: [10,10]
    Output: false
    

    Example 4:

    Input: [5,5,10,10,20]
    Output: false
    Explanation: 
    From the first two customers in order, we collect two $5 bills.
    For the next two customers in order, we collect a $10 bill and give back a $5 bill.
    For the last customer, we can't give change of $15 back because we only have two $10 bills.
    Since not every customer received correct change, the answer is false.
    

    Note:

    • 0 <= bills.length <= 10000
    • bills[i] will be either 5, 10, or 20.
    class Solution {
        public boolean lemonadeChange(int[] bills) {
            int[] bucks = new int[2];
            for (int bill : bills) {
                if (bill == 5) {
                    bucks[0]++;
                } else if (bill == 10) {
                    if (bucks[0] == 0) return false;
                    bucks[0]--;
                    bucks[1]++;
                } else if (bucks[1] > 0) {
                    bill -= 10;
                    bucks[1] --;
                    if (bucks[0] == 0) return false;
                    bucks[0]--;
                } else {
                    if (bucks[0] < 3) return false;
                    bucks[0] -= 3;
                }
            }
            return true;
        }
    }
    
  • 200. Number of Islands

    Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.

    An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

    Example 1:

    Input: grid = [
      ["1","1","1","1","0"],
      ["1","1","0","1","0"],
      ["1","1","0","0","0"],
      ["0","0","0","0","0"]
    ]
    Output: 1
    

    Example 2:

    Input: grid = [
      ["1","1","0","0","0"],
      ["1","1","0","0","0"],
      ["0","0","1","0","0"],
      ["0","0","0","1","1"]
    ]
    Output: 3
    

    Constraints:

    • m == grid.length
    • n == grid[i].length
    • 1 <= m, n <= 300
    • grid[i][j] is '0' or '1'.
    class Solution {
        int[][] directs = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
        public int numIslands(char[][] grid) {
            int res = 0;
            int m = grid.length, n = grid[0].length;
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (grid[i][j] == '0') continue;
                    res++;
                    sink(grid, i, j);
                }
            }
            return res;
        }
    
        private void sink(char[][] grid, int i, int j) {
            grid[i][j] = '0';
            for (int[] dir : directs) {
                int x = i + dir[0], y = j + dir[1];
                if (in(grid, x, y) && grid[x][y] == '1') {
                    sink(grid, x, y);
                }
            }
        }
    
        private boolean in(char[][] grid, int x, int y) {
            return x >= 0 && y >= 0 && x < grid.length && y < grid[0].length;
        }
    }
    
  • 874. Walking Robot Simulation

    A robot on an infinite XY-plane starts at point (0, 0) and faces north. The robot can receive one of three possible types of commands:

    • -2: turn left 90 degrees,
    • -1: turn right 90 degrees, or
    • 1 <= k <= 9: move forward k units.

    Some of the grid squares are obstacles. The ith obstacle is at grid point obstacles[i] = (xi, yi).

    If the robot would try to move onto them, the robot stays on the previous grid square instead (but still continues following the rest of the route.)

    Return the maximum Euclidean distance that the robot will be from the origin squared (i.e. if the distance is 5, return 25).

    Note:

    • North means +Y direction.
    • East means +X direction.
    • South means -Y direction.
    • West means -X direction.

    Example 1:

    Input: commands = [4,-1,3], obstacles = []
    Output: 25
    Explanation: The robot starts at (0, 0):
    1. Move north 4 units to (0, 4).
    2. Turn right.
    3. Move east 3 units to (3, 4).
    The furthest point away from the origin is (3, 4), which is 32 + 42 = 25 units away.
    

    Example 2:

    Input: commands = [4,-1,4,-2,4], obstacles = [[2,4]]
    Output: 65
    Explanation: The robot starts at (0, 0):
    1. Move north 4 units to (0, 4).
    2. Turn right.
    3. Move east 1 unit and get blocked by the obstacle at (2, 4), robot is at (1, 4).
    4. Turn left.
    5. Move north 4 units to (1, 8).
    The furthest point away from the origin is (1, 8), which is 12 + 82 = 65 units away.
    

    Constraints:

    • 1 <= commands.length <= 104
    • commands[i] is one of the values in the list [-2,-1,1,2,3,4,5,6,7,8,9].
    • 0 <= obstacles.length <= 104
    • -3 * 104 <= xi, yi <= 3 * 104
    • The answer is guaranteed to be less than 231.
    class Solution {
        int[][] dirs = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}}; // ->left  <-right
        Set<String> set = new HashSet<>();
        int max = 0;
        public int robotSim(int[] commands, int[][] obstacles) {
            int[] pos = {0, 0};
            for (int[] obstacle : obstacles) {
                set.add(""+obstacle[0]+","+obstacle[1]);
            }
            dfs(pos, 0, commands, 0);
            return max;
        }
    
        private void dfs(int[] pos, int face, int[] commands, int i) {
            if (i == commands.length) return;
            if (commands[i] < 0) {
                face = (face + (commands[i] == -2 ? 1 : 3)) % 4;
                i++;
            } else {
                int[] next = {pos[0] + dirs[face][0], pos[1] + dirs[face][1]};
                if (set.contains(""+next[0]+","+next[1])) {
                    i++;
                } else {
                    commands[i]--;
                    pos[0] = next[0];
                    pos[1] = next[1];
                    max = Math.max(max, pos[0]*pos[0] + pos[1]*pos[1]);
                    if (commands[i] == 0) i++;
                }
            }
            dfs(pos, face, commands, i);
        }
    }
    
  • 127. Word Ladder

    A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words such that:

    • The first word in the sequence is beginWord.
    • The last word in the sequence is endWord.
    • Only one letter is different between each adjacent pair of words in the sequence.
    • Every word in the sequence is in wordList.

    Given two words, beginWord and endWord, and a dictionary wordList, return the number of words in the shortest transformation sequence from beginWord to endWord, or 0 if no such sequence exists.

    Example 1:

    Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
    Output: 5
    Explanation: One shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog" with 5 words.
    

    Example 2:

    Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
    Output: 0
    Explanation: The endWord "cog" is not in wordList, therefore there is no possible transformation.
    

    Constraints:

    • 1 <= beginWord.length <= 10
    • endWord.length == beginWord.length
    • 1 <= wordList.length <= 5000
    • wordList[i].length == beginWord.length
    • beginWord, endWord, and wordList[i] consist of lowercase English letters.
    • beginWord != endWord
    • All the strings in wordList are unique.
    class Solution {
        public int ladderLength(String beginWord, String endWord, List<String> wordList) {
            Deque<String> deque = new LinkedList<>();
            deque.addLast(beginWord);
            Set<String> set = new HashSet<>();
            int res = 0;
            while (!deque.isEmpty()) {
                int size = deque.size();
                res++;
                while (size-- > 0) {
                    String s = deque.pollFirst();
                    if (s.equals(endWord)) return res;
                    for (String t : wordList) {
                        if (set.size() == wordList.size()) break;
                        if (set.contains(t)) continue;
                        if (can(s, t)) {
                            deque.addLast(t);
                            set.add(t);
                        }
                    }
                }
            }
            return 0;
        }
        private boolean can(String s, String t) {
            boolean flag = true;
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) != t.charAt(i)) {
                    if (flag) flag = false;
                    else return false;
                }
            }
            return true;
        }
    }
    
posted @ 2021-03-17 14:17  鹏懿如斯  阅读(58)  评论(0编辑  收藏  举报