找到下一个按照字典序的排列,所以思路应该是从排列的尾部开始找。
首先从排列的尾部往前找,找到第一个 nums[ i-1 ] < nums[ i ] 的位置,此时说明通过将 nums[ i-1 ] 和排列在 nums[ i-1 ] 后面的并且比 nums[ i-1 ] 大的数 nums[ j ] 互换位置,将得到更大的排列。
如果找不到 nums[ i-1 ] < nums[ i ] 的位置,则说明此时的排列是最大的,直接将整个排列进行反转,得到最小的排列。
若找到 nums[ i-1 ] < nums[ i ] 的位置,此时的任务是找到一个数和 nums[ i-1 ] 进行交换,这个数需要满足:这个数排列在 nums[ i-1 ] 的后面,并且是比 nums[ i-1 ] 大的数中最小的那一个数。
完成交换后,由于 nums[ i-1 ] 已经比之前更大了,所以需要将排在 nums[ i-1 ] 后面的数变为最小的排列,即把在 nums[ i-1 ] 后面的排列进行反转。
完成交换和反转之后便得到了下一个按照字典序的排列。
class Solution {
public:
void nextPermutation(vector& nums) {
int pos = nums.size()-1;
while(pos > 0 && nums[pos] <= nums[pos-1])
pos--;
reverse(nums.begin()+pos,nums.end());
if(pos > 0){
for(int i=pos;i nums[pos-1]){
swap(nums[pos-1],nums[i]);
break;
}
}
}
return;
}
};
class Solution {
public:
int longestValidParentheses(string s) {
int ans = 0;
int len = s.length();
vector dp(len, 0);
for(int i=1; i0 ? dp[i-2]+2 : 2;
}
else if( i-1-dp[i-1] >=0 && s[i-1-dp[i-1]] == '('){
if( i-dp[i-1]-2 >= 0){
dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2];
}
else{
dp[i] = dp[i-1] + 2;
}
}
}
ans = max(ans, dp[i]);
}
return ans;
}
};
在栈中的栈底元素是此时有效括号字符串的开始位置。
class Solution {
public:
int longestValidParentheses(string s) {
int ans = 0;
int len = s.length();
stack front;
front.push(-1);
for(int i=0; i
由于该“旋转有序数组”的特性,在对其进行划分时,划分出来的两个部分一定有一部分是完全有序的,另一部分是部分有序的。
根据这个特性,我们可以取出两个部分中完全有序的那一部分进行讨论:
由于数组是完全有序的,所以可以通过判断大小知道目标数字是否在这一部分。
如果目标数字不在完全有序的那一部分,那么一定在另一部分。
通过上述的判断可以进行二分查找,不断缩小查找范围,直到找到目标数字的位置或者没找到目标数字。
class Solution {
public:
int search(vector& nums, int target) {
int left = 0,right = nums.size()-1;
while(left <= right){
if(left == right){
if(nums[left] == target)
return left;
else
return -1;
}
int mid = (left + right)/2;
if(nums[mid] == target)
return mid;
if(nums[left] <= nums[mid]){
if(nums[left] <= target && target < nums[mid]){
right = mid;
continue;
}
else{
left = mid+1;
continue;
}
}
else{
if(nums[mid] < target && target <= nums[right]){
left = mid+1;
continue;
}
else{
right = mid;
continue;
}
}
}
return -1;
}
};
二分法的重点和难点主要为:
class Solution {
public:
vector searchRange(vector& nums, int target) {
int left = 0,right = nums.size();
vector ans = {-1,-1};
while(left < right){
int mid = left + (right - left)/2;
if(nums[mid] == target)
right = mid;
else if(nums[mid] < target)
left = mid+1;
else if(nums[mid] > target)
right = mid;
}
if(left < nums.size() && nums[left] == target)
ans[0] = left;
left = 0,right = nums.size();
while(left < right){
int mid = left + (right - left)/2;
if(nums[mid] == target)
left = mid+1;
else if(nums[mid] < target)
left = mid+1;
else if(nums[mid] > target)
right = mid;
}
if(right-1 < nums.size() && nums[right-1] == target)
ans[1] = right-1;
return ans;
}
};
class Solution {
public:
int searchInsert(vector& nums, int target) {
int left = 0,right = nums.size()-1;
while(left <= right){
int mid = left + (right - left)/2;
if(nums[mid] == target)
return mid;
else if(nums[mid] < target)
left = mid+1;
else if(nums[mid] > target)
right = mid-1;
}
return left;
}
};