class Solution {
public:
void nextPermutation(vector<int>& nums) {
int k = nums.size() - 1;
// 1. 找到第一个递减点 e,g, 1,2,3 -> 1,3,2
while(k > 0 && nums[k - 1] >= nums[k]) k--;
if(k == 0) reverse(nums.begin(), nums.end()); // 如果降序排列 直接反转
else
{
// 2. 找到 k - 1 右边第一个比nums[k - 1]大的元素
//int i = nums.size() - 1;
//while(i > k && nums[i] <= nums[k - 1]) i--;
int l = k, r = nums.size() - 1;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(nums[mid] > nums[k - 1]) l = mid;
else r = mid - 1;
}
swap(nums[k - 1], nums[r]);
// 交换完之后仍然是降序(字典序最大) 转换为升序(字典序最小)
reverse(nums.begin() + k, nums.end());
}
}
};
- 经典劝退题
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> stk;
int res = 0;
for(int i = 0, start = -1; i < s.size(); i++)
{
if(s[i] == '(') stk.push(i);
else
{
if(stk.size())
{
stk.pop();
if(stk.size())
res = max(res, i - stk.top());
else
res = max(res, i - start);
}
else
{
start = i;
}
}
}
return res;
}
};
class Solution {
public:
int search(vector<int>& nums, int target) {
if(nums.empty()) return -1;
// 1. 二分查找分界线
int l = 0, r = nums.size() - 1;
while(l < r)
{
int mid = l + r + 1 >> 1;
if (nums[mid] >= nums[0]) l = mid;
else r = mid - 1;
}
// 左边的一段 or 右边的一段
if(target >= nums[0]) l = 0; // r = r;
else l++, r = nums.size() - 1;
// 正常的二分查找
while(l < r)
{
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
return nums[r] == target ? l : -1;
}
};
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> res = {-1, -1};
if(nums.empty()) return res;
// 二分左边界
int l = 0, r = nums.size() - 1;
while(l < r)
{
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
if(nums[l] != target) return res;
// 二分右边界
else res[0] = l;
r = nums.size() - 1;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(nums[mid] <= target) l = mid;
else r = mid - 1;
}
res[1] = l;
return res;
}
};
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(nums.empty()) return 0;
int l = 0, r = nums.size() - 1;
while(l < r)
{
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
if(nums[l] < target) l++;
return l;
}
};