Q****1025. Divisor Game
Alice and Bob take turns playing a game, with Alice starting first.
Initially, there is a number N on the chalkboard. On each player's turn, that player makes a
move
consisting of:
- Choosing any
xwith0 < x < NandN % x == 0. - Replacing the number
Non the chalkboard withN - x.
Also, if a player cannot make a move, they lose the game.
Return True if and only if Alice wins the game, assuming both players play optimally.
Example 1:
Input: 2
Output: true
Explanation: Alice chooses 1, and Bob has no more moves.
Example 2:
Input: 3
Output: false
Explanation: Alice chooses 1, Bob chooses 1, and Alice has no more moves.
Note:
1 <= N <= 1000
解法及注释
class Solution {
public boolean divisorGame(int N) {
//Approach 1: analyis
return N % 2 == 0;
//Approach 2: use dynamic programming
//return useDp(N);
}
private boolean useDp(int N) {
if(N == 1)
return false;
int[] dp = new int[N];
dp[0] = 0;
for(int i = 1; i < dp.length; i++){
dp[i] = N == 1 ? 1 : --N;
}
return dp.length % 2 == 0 ? dp[dp.length-1] == 1 : dp[dp.length-1] != 1;
}
}
Q****1143. Longest Common Subsequence
Given two strings text1 and text2, return the length of their longest common subsequence. A subsequence of a string is a new string generated from the original string with some characters(can be none) deleted without changing the relative order of the remaining characters. (eg, "ace" is a subsequence of "abcde" while "aec" is not). A common subsequence of two strings is a subsequence that is common to both strings.
If there is no common subsequence, return 0.
Example 1:
Input: text1 = "abcde", text2 = "ace"
Output: 3
Explanation: The longest common subsequence is "ace" and its length is 3.
Example 2:
Input: text1 = "abc", text2 = "abc"
Output: 3
Explanation: The longest common subsequence is "abc" and its length is 3.
Example 3:
Input: text1 = "abc", text2 = "def"
Output: 0
Explanation: There is no such common subsequence, so the result is 0.
Constraints:
1 <= text1.length <= 10001 <= text2.length <= 1000- The input strings consist of lowercase English characters only.
解法及注释
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
//pre-check
if(text1 == null || text2 == null)
return 0;
if(text1.length() == 0 || text2.length() == 0)
return 0;
int m = text1.length();
int n = text2.length();
int[][] res = new int[m+1][n+1];
for(int i = 1; i <= m; i++) {
for(int j = 1; j <= n; j++) {
//if the last character match, res[i][j] = res[i-1][j-1]+1;
if(text1.charAt(i-1) == text2.charAt(j-1))
res[i][j] = res[i-1][j-1] + 1;
//if the last character does not match, res[i][j] either come from res[i-1][j] or res[i][j-1]
else
res[i][j] = Math.max(res[i-1][j], res[i][j-1]);
}
}
return res[m][n];
}
}
Q****1277. Count Square Submatrices with All Ones
Given a m * n matrix of ones and zeros, return how many square submatrices have all ones.
Example 1:
Input: matrix =
[
[0,1,1,1],
[1,1,1,1],
[0,1,1,1]
]
Output: 15
Explanation:
There are 10 squares of side 1.
There are 4 squares of side 2.
There is 1 square of side 3.
Total number of squares = 10 + 4 + 1 = 15.
Example 2:
Input: matrix =
[
[1,0,1],
[1,1,0],
[1,1,0]
]
Output: 7
Explanation:
There are 6 squares of side 1.
There is 1 square of side 2.
Total number of squares = 6 + 1 = 7.
Constraints:
1 <= arr.length <= 3001 <= arr[0].length <= 3000 <= arr[i][j] <= 1
解法及注释
class Solution {
public int countSquares(int[][] matrix) {
if(matrix == null)
return 0;
int res = 0;
int row = matrix.length, col = matrix[0].length;
for(int i = 0; i < row; i++) {
for(int j = 0; j < col; j++) {
if((i ==0 || j ==0) && matrix[i][j] == 1)
res++;
else if(matrix[i][j] == 1) {
matrix[i][j] = Math.min(matrix[i - 1][j - 1], Math.min(matrix[i - 1][j], matrix[i][j - 1])) + 1;
res += matrix[i][j];
}
}
}
return res;
}
}
Q****1641. Count Sorted Vowel Strings
Given an integer n, return the number of strings of length n that consist only of vowels (a,e,i,o,u) and are lexicographically sorted.
A string s is lexicographically sorted if for all valid i, s[i] is the same as or comes before s[i+1] in the alphabet.
Example 1:
Input: n = 1
Output: 5
Explanation: The 5 sorted strings that consist of vowels only are ["a","e","i","o","u"].
Example 2:
Input: n = 2
Output: 15
Explanation: The 15 sorted strings that consist of vowels only are
["aa","ae","ai","ao","au","ee","ei","eo","eu","ii","io","iu","oo","ou","uu"].
Note that "ea" is not a valid string since 'e' comes after 'a' in the alphabet.
Example 3:
Input: n = 33
Output: 66045
Constraints:
1 <= n <= 50
解法及注释
class Solution {
public int countVowelStrings(int n) {
int[] res = new int[5];
for(int i =0; i < 5; i++)
res[i] = 1;
for(int j = 1; j <= n; j++) {
for(int i = 1; i <5; i++)
res[i] += res[i - 1];
}
return res[4];
}
}
Q****121. Best Time to Buy and Sell Stock
You are given an array prices where prices[i] is the price of a given stock on the ith day.
You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.
Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.
Example 1:
Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.
Example 2:
Input: prices = [7,6,4,3,1]
Output: 0
Explanation: In this case, no transactions are done and the max profit = 0.
Constraints:
1 <= prices.length <= 1050 <= prices[i] <= 104
解法及注释
class Solution {
public int maxProfit(int[] prices) {
if(prices == null || prices.length == 0)
return 0;
int min = Integer.MAX_VALUE;
int maxProfit = 0;
for(int i = 0; i < prices.length; i++) {
if(prices[i] < min)
min = prices[i];
else if(prices[i] - min > maxProfit)
maxProfit = prices[i] - min;
}
return maxProfit;
}
}
Q****123. Best Time to Buy and Sell Stock III
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example 1:
Input: prices = [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 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.
Example 4:
Input: prices = [1]
Output: 0
Constraints:
1 <= prices.length <= 1050 <= prices[i] <= 105
解法及注释(TimeLimit Exceeds)
class Solution {
public int maxProfit(int[] prices) {
if(prices == null || prices.length < 2)
return 0;
int oneTrans = getMaxProfit(prices, 0, prices.length - 1);
int twoTrans = 0;
for(int i = 1; i < prices.length - 1; i++) {
twoTrans = Math.max(twoTrans, getMaxProfit(prices, 0, i) + getMaxProfit(prices, i + 1, prices.length - 1));
}
return Math.max(oneTrans, twoTrans);
}
private int getMaxProfit(int[] prices, int start, int end) {
int min = Integer.MAX_VALUE;
int maxProfit = 0;
for(int i = start; i <= end; i++) {
if(prices[i] < min)
min = prices[i];
else if(prices[i] - min > maxProfit)
maxProfit = prices[i] - min;
}
return maxProfit;
}
}
解法及注释
class Solution {
public int maxProfit(int[] prices) {
if(prices == null || prices.length < 2)
return 0;
int buy1 = -prices[0], buy2 = -prices[0];
int profit1 = 0, total = 0;
for(int price : prices) {
buy1 = Math.max(buy1, -price);
profit1 = Math.max(profit1, buy1 + price);
buy2 = Math.max(buy2, profit1 + (-price));
total = Math.max(total, buy2 + price);
}
return total;
}
}
Q****188. Best Time to Buy and Sell Stock IV
You are given an integer array prices where prices[i] is the price of a given stock on the ith day.
Design an algorithm to find the maximum profit. You may complete at most k transactions.
Notice that you may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
Example 1:
Input: k = 2, prices = [2,4,1]
Output: 2
Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.
Example 2:
Input: k = 2, prices = [3,2,6,5,0,3]
Output: 7
Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4. Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Constraints:
0 <= k <= 1000 <= prices.length <= 10000 <= prices[i] <= 1000
解法及注释
class Solution {
public int maxProfit(int k, int[] prices) {
if(prices == null || prices.length == 0 || k <= 0)
return 0;
int n = prices.length;
if(k * 2 > n) {
int res = 0;
for(int i = 1; i < n; i++) {
res += Math.max(0, prices[i] - prices[i - 1]);
}
return res;
}
// dp[i][used_k][ishold] = balance
// ishold: 0 nothold, 1 hold
int[][][] dp = new int[n][k+1][2];
//initialize the array with minus int value to prevent overflow
for(int i = 0; i < n; i++) {
for(int j = 0; j <= k; j++) {
dp[i][j][0] = -1000000000;
dp[i][j][1] = -1000000000;
}
}
//set start value
dp[0][0][0] = 0;
dp[0][1][1] = -prices[0];
/* 1. Keep holding the stock:
dp[i][j][1]=dp[i−1][j][1]
2. Keep not holding the stock:
dp[i][j][0]=dp[i−1][j][0]
3. Buying, when j>0:
dp[i][j][1]=dp[i−1][j−1][0]−prices[i]
4. Selling
dp[i][j][0]=dp[i−1][j][1]+prices[i]
We can combine they together to find the maximum profit:
dp[i][j][0]=max(dp[i−1][j][0],dp[i−1][j][1]+prices[i])
dp[i][j][1]=max(dp[i−1][j][1],dp[i−1][j−1][0]−prices[i])
*/
for(int i = 1; i < n; i++) {
for(int j = 0; j <= k; j++) {
dp[i][j][0] = Math.max(dp[i-1][j][0], dp[i-1][j][1] + prices[i]);
if(j > 0)
dp[i][j][1] = Math.max(dp[i-1][j][1], dp[i-1][j - 1][0] - prices[i]);
}
}
int res = 0;
for(int i = 0; i <=k; i++)
res = Math.max(res, dp[n -1][i][0]);
return res;
}
}
Q****309. Best Time to Buy and Sell Stock with Cooldown
Say you have an array for which the _i_th element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
- You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
- After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
Example:
Input: [1,2,3,0,2]
Output: 3
Explanation: transactions = [buy, sell, cooldown, buy, sell]
解法及注释
class Solution {
public int maxProfit(int[] prices) {
if(prices == null || prices.length < 2)
return 0;
int n = prices.length;
int buy = -prices[0], sell = 0, cooldown = 0;
for(int i = 1; i < n; i++) {
int tempBuy = Math.max(buy, cooldown - prices[i]);
//assume cooldown is the value as sell
cooldown = sell;
sell = Math.max(sell, buy + prices[i]);
buy = tempBuy;
}
return sell;
}
}
Q****132. Palindrome Partitioning II
Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
Example 1:
Input: s = "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
Example 2:
Input: s = "a"
Output: 0
Example 3:
Input: s = "ab"
Output: 1
Constraints:
1 <= s.length <= 2000sconsists of lower-case English letters only.
**解法及注释
**
class Solution {
public int minCut(String s) {
if(s == null || s.length() < 2)
return 0;
char[] chars = s.toCharArray();
int len = s.length();
boolean[][] dp = new boolean[len][len];
int cut[] = new int[len];
//single character
for(int i = 0; i < len; i++)
dp[i][i] = true;
//double character
for(int i = 0; i < len - 1; i++) {
if(chars[i] == chars[i + 1])
dp[i][i + 1] = true;
}
//n characters
for(int i = 3; i <= len; i++) {
for(int j = 0; j < len - i + 1; j++) {
int k = i + j - 1;
if(chars[j] == chars[k] && dp[j + 1][k - 1])
dp[j][k] = true;
}
}
for(int i = 0; i < len; i++) {
if(dp[0][i])
cut[i] = 0; //already palindrome
else {
cut[i] = Integer.MAX_VALUE;
for(int j = 0; j < i; j++) {
if((dp[j + 1][i] == true) && (cut[j] + 1 < cut[i]))
cut[i] = 1 + cut[j];
}
}
}
return cut[len - 1];
}
}
Q****32. Longest Valid Parentheses
Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: s = "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()".
Example 2:
Input: s = ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()".
Example 3:
Input: s = ""
Output: 0
Constraints:
0 <= s.length <= 3 * 104s[i]is'(', or')'.
解法及注释
public class Solution {
public int longestValidParentheses(String s) {
int max = 0;
int dp[] = new int[s.length()];
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) == ')') {
if (s.charAt(i - 1) == '(') {
dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
} else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
}
max = Math.max(max, dp[i]);
}
}
return max;
}
}