You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Question: Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). The replacement must be in-place, do not allocate extra memory.
Idea: Back tracking:
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n = nums.size();
if(n<=1) return;
int j = n-1, k = n-1;
while(j && nums[j-1]>=nums[j]) --j;
if(j){
while(nums[k] <= nums[j-1]) --k;
swap(nums[k],nums[j-1]);
}
reverse(nums.begin()+j,nums.end());
}
};
32, Longest Valid Parentheses
Question: Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring is "()", which has length = 2.
Idea: Using dp and for every step, there are several possibilities: dp[i] is the longest length of valid paranthese that ends at i:
1, s[i] == '(' then dp[i] = 0;
2, s[i] == ')' then the configuration should be (....)(...), and we try to find where the intermediate '(' and ')' are and dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2];
class Solution {
public:
int longestValidParentheses(string s) {
int n = s.size();
if(n<=1) return 0;
vector<int> dp(n,0);
dp[1] = s[0]=='(' && s[1]==')'? 2:0;
int mL = dp[1];
for(int i=2;i<n;++i){
if(s[i]=='(') continue;
if(s[i-1]=='(') dp[i] = dp[i-2] + 2;
else {
if(!(i-dp[i-1])) dp[i] = 0;
else if(s[i-dp[i-1]-1]=='('){
dp[i] = dp[i-1]+2;
if(i-dp[i-1]-2>=0) dp[i] += dp[i-dp[i-1]-2];
}
}
mL = max(mL,dp[i]);
}
return mL;
}
};
33, Search in Rotated Sorted Array
Question: Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no duplicate exists in the array.
Idea: find the pivat first, and then find the value. Both steps use binary search.
class Solution {
public:
int search(vector<int>& nums, int target) {
if(nums.empty()) return -1;
int n = nums.size();
int p = 0;
if(nums[0]>nums[n-1]){
int l = 0;
p = n-1;
while(l<p-1){
int c = (l+p)/2;
if(nums[c]>nums[0]) l = c;
else p = c;
}
}
if(target < nums[p]) return -1;
int l = 0, r = n;
while(l<r-1){
int c = (l+r)/2;
if(nums[(p+c)%n] > target) r = c;
else l = c;
}
return nums[(l+p)%n]==target? (l+p)%n:-1;
}
};
34, Search for a Range
Question: Given an array of integers sorted in ascending order, find the starting and ending position of a given target value. Your algorithm's runtime complexity must be in the order of O(log n). If the target is not found in the array, return [-1, -1].
Idea: Simple binary search
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.empty() || nums[nums.size()-1]<target) return vector<int>{-1,-1};
int i = -1, l = nums.size()-1;
while(i<l-1){
int c = (i+l)/2;
if(nums[c]<target) i = c;
else l = c;
}
if(nums[l] != target) return vector<int>{-1,-1};
int r = l;
i = nums.size();
while(r<i-1){
int c = (i+r)/2;
if(nums[c]==target) r = c;
else i = c;
}
return vector<int>{l,r};
}
};
35, Search Insert Position
Question: Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array.
Idea: Simple binary search.
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(nums.empty() || nums[nums.size()-1]<target) return nums.size();
int l = -1, r = nums.size()-1;
while(l<r-1){
int c = (l+r)/2;
if(nums[c]<target) l = c;
else r = c;
}
return r;
}
};
Question: Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times.
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Question: Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. Each number in C may only be used once in the combination.
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Question: Given an unsorted integer array, find the first missing positive integer. For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.
Your algorithm should run in O(n) time and uses constant space.
Idea: transform
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for(int i=0;i<n;){
if(nums[i]<=0 || nums[i]>n || nums[i]==i+1 || nums[nums[i]-1]==nums[i]) ++i;
else swap(nums[nums[i]-1],nums[i]);
}
for(int i=0;i<n;++i) if(nums[i]!=i+1) return i+1;
return n+1;
}
};
42, Trapping Rain Water
Question: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
Idea: Bury approach: (We can also use the maximum until i to determine the water level.)
class Solution {
public:
int trap(vector<int>& height) {
if(height.empty()) return 0;
int i = 0, j = height.size()-1, ans = 0;
for(int l = height[i],r = height[j];i<j-1;){
if(l<r){
++i;
if(l>height[i]) ans += l-height[i];
else l = height[i];
}
else{
--j;
if(r>height[j]) ans += r-height[j];
else r = height[j];
}
}
return ans;
}
};
43, Multiply Strings
Question: Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2
Idea: Just do it: Consider the carrier of each digit
class Solution {
public:
string multiply(string num1, string num2) {
if(num1=="0" || num2=="0") return "0";
reverse(num1.begin(),num1.end());
reverse(num2.begin(),num2.end());
string ans;
for(int i=0,cur=0;i<num1.size()+num2.size()-1||cur;i++){
for(int j=max(i+1-(int)num2.size(),0);j<=min(i,(int)num1.size()-1);++j) cur += int(num1[j]-'0')*int(num2[i-j]-'0');
ans += (char)(cur%10 + (int)'0');
cur /= 10;
}
reverse(ans.begin(),ans.end());
return ans;
}
};
44, Wildcard Matching
Question: Implement wildcard pattern matching with support for '?' and '*'.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
Idea: the same dp[i][j] as the previous one: (400 ms, needs optimization!)
Given an array of non-negative integers, 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.
Idea: Easy Greedy!
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size();
if(n<=1) return 0;
int ans = 1;
for(int i=0,p=nums[0];p<n-1;ans++){
int tmp = p;
for(;i<=p;++i) tmp = max(tmp,i+nums[i]);
p = tmp;
}
return ans;
}
};