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 factorg[i]
, which is the minimum size of a cookie that the child will be content with; and each cookiej
has a sizes[j]
. Ifs[j] >= g[i]
, we can assign the cookiej
to the childi
, and the childi
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
whereprices[i]
is the price of a given stock on theith
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 either5
,10
, or20
.
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 gridgrid
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 ofcommands
:-2
: turn left90
degrees,-1
: turn right90
degrees, or1 <= k <= 9
: move forwardk
units.
Some of the grid squares are
obstacles
. Theith
obstacle is at grid pointobstacles[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
, return25
).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 wordendWord
using a dictionarywordList
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
andendWord
, and a dictionarywordList
, return the number of words in the shortest transformation sequence frombeginWord
toendWord
, or0
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
, andwordList[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; } }
- The first word in the sequence is