https://leetcode-cn.com/problems/first-missing-positive/solution/que-shi-de-di-yi-ge-zheng-shu-by-leetcode-solution/
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for (int& num: nums) {
if (num <= 0) {
num = n + 1;
}
}
for (int i = 0; i < n; ++i) {
int num = abs(nums[i]);
if (num <= n) {
nums[num - 1] = -abs(nums[num - 1]);
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] > 0) {
return i + 1;
}
}
return n + 1;
}
};
https://leetcode-cn.com/problems/trapping-rain-water/solution/jie-yu-shui-by-leetcode-solution-tuvc/
找左右两边最大值中小者,减去本身高度
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
if (n == 0) {
return 0;
}
vector<int> leftMax(n);
leftMax[0] = height[0];
for (int i = 1; i < n; ++i) {
leftMax[i] = max(leftMax[i - 1], height[i]);
}
vector<int> rightMax(n);
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; --i) {
rightMax[i] = max(rightMax[i + 1], height[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += min(leftMax[i], rightMax[i]) - height[i];
}
return ans;
}
};
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector <int> ans;
if(matrix.empty()) return ans; //若数组为空,直接返回答案
int u = 0; //赋值上下左右边界
int d = matrix.size() - 1;
int l = 0;
int r = matrix[0].size() - 1;
while(true)
{
for(int i = l; i <= r; ++i) ans.push_back(matrix[u][i]); //向右移动直到最右
if(++ u > d) break; //重新设定上边界,若上边界大于下边界,则遍历遍历完成,下同
for(int i = u; i <= d; ++i) ans.push_back(matrix[i][r]); //向下
if(-- r < l) break; //重新设定有边界
for(int i = r; i >= l; --i) ans.push_back(matrix[d][i]); //向左
if(-- d < u) break; //重新设定下边界
for(int i = d; i >= u; --i) ans.push_back(matrix[i][l]); //向上
if(++ l > r) break; //重新设定左边界
}
return ans;
}
};
https://leetcode-cn.com/problems/merge-intervals/solution/merge-intervals-by-ikaruga/
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end());
vector<vector<int>> ans;
for (int i = 0; i < intervals.size();) {
int t = intervals[i][1];
int j = i + 1;
while (j < intervals.size() && intervals[j][0] <= t) {
t = max(t, intervals[j][1]);
j++;
}
ans.push_back({ intervals[i][0], t });
i = j;
}
return ans;
}
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> ans;
bool flag = false; //新区间是否放置进答案
for(int i = 0; i < intervals.size(); i++){
if(newInterval[0] > intervals[i][1]){
ans.push_back(intervals[i]);
continue;
}
if(newInterval[1] < intervals[i][0]){
ans.push_back(newInterval);
flag = !flag;
for(; i < intervals.size(); i++)
ans.push_back(intervals[i]);
break;
}
newInterval[0] = min(newInterval[0], intervals[i][0]); //区间合并
newInterval[1] = max(newInterval[1], intervals[i][1]);
}
if(!flag)
ans.push_back(newInterval);
return ans;
}
};
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
// 创建二维矩阵
vector<vector<int>> matrix(n);
for (int i = 0; i < matrix.size(); i++)
matrix[i].resize(n);
// 上下左右
int u = 0;
int d = n-1;
int l = 0;
int r = n-1;
int num = 1;
while(true){
// 上
for(int i=l; i <= r; i++) matrix[u][i] = num++;
if (u++ >= d) break;
// 右
for(int i=u; i <= d; i++) matrix[i][r] = num++;
if (r-- <= l) break;
// 下
for(int i=r; i >= l; i--) matrix[d][i] = num++;
if (d-- <= u) break;
// 左
for(int i=d; i >= u; i--) matrix[i][l] = num++;
if (l++ >= r) break;
}
return matrix;
}
};
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
if (grid.size() == 0 || grid[0].size() == 0) {
return 0;
}
int rows = grid.size(), columns = grid[0].size();
auto dp = vector < vector <int> > (rows, vector <int> (columns));
dp[0][0] = grid[0][0];
for (int i = 1; i < rows; i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
for (int j = 1; j < columns; j++) {
dp[0][j] = dp[0][j - 1] + grid[0][j];
}
for (int i = 1; i < rows; i++) {
for (int j = 1; j < columns; j++) {
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
return dp[rows - 1][columns - 1];
}
};
https://leetcode-cn.com/problems/set-matrix-zeroes/solution/ju-zhen-zhi-ling-by-leetcode-solution-9ll7/
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
int flag_col0 = false, flag_row0 = false;
for (int i = 0; i < m; i++) {
if (!matrix[i][0]) {
flag_col0 = true;
}
}
for (int j = 0; j < n; j++) {
if (!matrix[0][j]) {
flag_row0 = true;
}
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (!matrix[i][j]) {
matrix[i][0] = matrix[0][j] = 0;
}
}
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (!matrix[i][0] || !matrix[0][j]) {
matrix[i][j] = 0;
}
}
}
if (flag_col0) {
for (int i = 0; i < m; i++) {
matrix[i][0] = 0;
}
}
if (flag_row0) {
for (int j = 0; j < n; j++) {
matrix[0][j] = 0;
}
}
}
};
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m = matrix.size(), n = matrix[0].size();
int low = 0, high = m * n - 1;
while (low <= high) {
int mid = (high - low) / 2 + low;
int x = matrix[mid / n][mid % n];
if (x < target) {
low = mid + 1;
} else if (x > target) {
high = mid - 1;
} else {
return true;
}
}
return false;
}
};
class Solution {
public:
void sortColors(vector<int>& nums) {
int n = nums.size();
int p0 = 0, p1 = 0;
for (int i = 0; i < n; ++i) {
if (nums[i] == 1) {
swap(nums[i], nums[p1]);
++p1;
} else if (nums[i] == 0) {
swap(nums[i], nums[p0]);
if (p0 < p1) {
swap(nums[i], nums[p1]);
}
++p0;
++p1;
}
}
}
};
class Solution {
public:
bool check(vector<vector<char>>& board, vector<vector<int>>& visited, int i, int j, string& s, int k) {
if (board[i][j] != s[k]) {
return false;
} else if (k == s.length() - 1) {
return true;
}
visited[i][j] = true;
vector<pair<int, int>> directions{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
bool result = false;
for (const auto& dir: directions) {
int newi = i + dir.first, newj = j + dir.second;
if (newi >= 0 && newi < board.size() && newj >= 0 && newj < board[0].size()) {
if (!visited[newi][newj]) {
bool flag = check(board, visited, newi, newj, s, k + 1);
if (flag) {
result = true;
break;
}
}
}
}
visited[i][j] = false;
return result;
}
bool exist(vector<vector<char>>& board, string word) {
int h = board.size(), w = board[0].size();
vector<vector<int>> visited(h, vector<int>(w));
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
bool flag = check(board, visited, i, j, word, 0);
if (flag) {
return true;
}
}
}
return false;
}
};
快慢指针
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if (n == 0) {
return 0;
}
int fast = 1, slow = 1;
while (fast < n) {
if (nums[fast] != nums[fast - 1]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
};
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if (n<=2) {
return n;
}
int fast = 2, slow = 2;
while (fast < n) {
if (nums[slow-2] != nums[fast]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
};
class Solution{
public:
int search(vector<int>& nums,int target){
int n=nums.size();
if(n==0)return -1;
if(n==1)return nums[0]==target?0:-1;
int l=0,r=n-1;
while(l<=r){
int mid=(l+r)/2;
if(nums[mid]==target)return mid;
if(nums[0]<=nums[mid]){
if(nums[0]<=target&&target<nums[mid]){
r=mid-1;
}else{
l=mid+1;
}
}else{
if(nums[mid]<target&&target<=nums[n-1]){
l=mid+1;
}else{
r=mid-1;
}
}
}
return -1;
}
};
class Solution {
public:
bool search(vector<int> &nums, int target) {
int n = nums.size();
if (n == 0) {
return false;
}
if (n == 1) {
return nums[0] == target;
}
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
++l;
--r;
} else if (nums[l] <= nums[mid]) {
if (nums[l] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return false;
}
};
class Solution {
public:
int largestRectangleArea(vector<int>& nums)
{
int maxval = 0;
//栈中存放的是索引,一定不要搞混淆了
stack<int> st;
nums.insert(nums.begin(),0);
nums.push_back(0);
for(size_t i=0;i<nums.size();++i)
{
while(!st.empty() && nums[i] < nums[st.top()])
{
int tmp = st.top();
st.pop();
int width = i-st.top()-1;
int height = nums[tmp];
maxval = max(maxval,width*height);
}
st.push(i);
}
return maxval;
}
};
https://leetcode-cn.com/problems/maximal-rectangle/solution/zui-da-ju-xing-by-leetcode-solution-bjlu/
法一:暴力解法
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
int m = matrix.size();
if (m == 0) {
return 0;
}
int n = matrix[0].size();
vector<vector<int>> left(m, vector<int>(n, 0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '1') {
left[i][j] = (j == 0 ? 0: left[i][j - 1]) + 1;
}
}
}
int ret = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '0') {
continue;
}
int width = left[i][j];
int area = width;
for (int k = i - 1; k >= 0; k--) {
width = min(width, left[k][j]);
area = max(area, (i - k + 1) * width);
}
ret = max(ret, area);
}
}
return ret;
}
};
法二:单调栈
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
int n = heights.size();
if(n==1) return heights[0];
vector<int> left(n,-1),right(n,n);
int ans = 0;
stack<int> upsk;
upsk.push(0);
for(int i=1;i<n;i++){
while(!upsk.empty()&&heights[upsk.top()]>heights[i]){
right[upsk.top()] = i;
upsk.pop();
}
if(!upsk.empty()){
left[i] = upsk.top();
upsk.push(i);
}
else upsk.push(i);
}
for(int i=0;i<n;i++){
ans = max(ans,heights[i]*(right[i]-left[i]-1));
}
return ans;
}
int maximalRectangle(vector<vector<char>>& matrix) {
int n = matrix.size();
if(n==0) return 0;
int m = matrix[0].size();
if(n==1&&m==1) return matrix[0][0]-'0';
vector<int> heights(m,0);
int ans = 0;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(matrix[i][j]-'0'==1) heights[j]++;
else heights[j] = 0;
}
ans = max(ans,largestRectangleArea(heights));
}
return ans;
}
};
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/cong-qian-xu-yu-zhong-xu-bian-li-xu-lie-gou-zao-9/
class Solution {
private:
unordered_map<int, int> index;
public:
TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
if (preorder_left > preorder_right) {
return nullptr;
}
// 前序遍历中的第一个节点就是根节点
int preorder_root = preorder_left;
// 在中序遍历中定位根节点
int inorder_root = index[preorder[preorder_root]];
// 先把根节点建立出来
TreeNode* root = new TreeNode(preorder[preorder_root]);
// 得到左子树中的节点数目
int size_left_subtree = inorder_root - inorder_left;
// 递归地构造左子树,并连接到根节点
// 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
root->left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
// 递归地构造右子树,并连接到根节点
// 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
root->right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
// 构造哈希映射,帮助我们快速定位根节点
for (int i = 0; i < n; ++i) {
index[inorder[i]] = i;
}
return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
};
class Solution {
private:
unordered_map<int,int>index;
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int n=postorder.size();
for(int i=0;i<n;++i){
index[inorder[i]]=i;
}
return myBuildTree(postorder,inorder,0,n-1,0,n-1);
}
TreeNode* myBuildTree(const vector<int>& postorder, const vector<int>& inorder, int postorder_left, int postorder_right, int inorder_left, int inorder_right) {
if(inorder_left>inorder_right){
return nullptr;
}
int postorder_root=postorder_right;
int inorder_root=index[postorder[postorder_root]];
TreeNode* root=new TreeNode(postorder[postorder_root]);
int size_left_subtree=inorder_root-inorder_left;
root->left=myBuildTree(postorder,inorder,postorder_left,postorder_left+size_left_subtree-1,inorder_left,inorder_root-1);
root->right=myBuildTree(postorder,inorder,postorder_left+size_left_subtree,postorder_right-1,inorder_root+1,inorder_right);
return root;
}
};
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> ret(numRows);
for (int i = 0; i < numRows; ++i) {
ret[i].resize(i + 1);
ret[i][0] = ret[i][i] = 1;
for (int j = 1; j < i; ++j) {
ret[i][j] = ret[i - 1][j] + ret[i - 1][j - 1];
}
}
return ret;
}
};
https://leetcode-cn.com/problems/triangle/solution/120-san-jiao-xing-zui-xiao-lu-jing-he-dpzi-shang-d/
方法一:动态规划
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int n = triangle.size();
vector<vector<int>> f(n, vector<int>(n));
f[0][0] = triangle[0][0];
for (int i = 1; i < n; ++i) {
f[i][0] = f[i - 1][0] + triangle[i][0];
for (int j = 1; j < i; ++j) {
f[i][j] = min(f[i - 1][j - 1], f[i - 1][j]) + triangle[i][j];
}
f[i][i] = f[i - 1][i - 1] + triangle[i][i];
}
return *min_element(f[n - 1].begin(), f[n - 1].end());
}
};
方法二:原地修改
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle)
{
for(int i=triangle.size()-2;i>=0;i--)//从最后第二层开始遍历(最后一层没必要进行遍历)
{
for(int j=0;j<triangle[i].size();j++)//遍历每层中的所有元素
{
//该层中元素重新赋值为其后一层相同下标或下标值+1与其之和的较小值
triangle[i][j]=min(triangle[i][j]+triangle[i+1][j],triangle[i][j]+triangle[i+1][j+1]);
}
}
return triangle[0][0];//最终返回首行首列元素即为最终结果
}
};
方法三:动态规划自下到上 一维数组
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int n = triangle.size();
// 一维数组dp记录遍历到每一行的每个节点的最小路径和
vector<int> dp(n + 1, 0);
// 从最后一行开始依次更新每一行的dp值
for(int i = n - 1; i >= 0; i--)
for(int j = 0; j< triangle[i].size(); j++)
dp[j] = triangle[i][j] + min(dp[j],dp[j+1]);
return dp[0];
}
};
https://leetcode-cn.com/problems/longest-consecutive-sequence/solution/zui-chang-lian-xu-xu-lie-by-leetcode-solution/
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> num_set;
for (const int& num : nums) {
num_set.insert(num);
}
int longestStreak = 0;
for (const int& num : num_set) {
if (!num_set.count(num - 1)) {
int currentNum = num;
int currentStreak = 1;
while (num_set.count(currentNum + 1)) {
currentNum += 1;
currentStreak += 1;
}
longestStreak = max(longestStreak, currentStreak);
}
}
return longestStreak;
}
};
class Solution {
public:
int n, m;
void dfs(vector<vector<char>>& board, int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m || board[x][y] != 'O') {
return;
}
board[x][y] = 'A';
dfs(board, x + 1, y);
dfs(board, x - 1, y);
dfs(board, x, y + 1);
dfs(board, x, y - 1);
}
void solve(vector<vector<char>>& board) {
n = board.size();
if (n == 0) {
return;
}
m = board[0].size();
for (int i = 0; i < n; i++) {
dfs(board, i, 0);
dfs(board, i, m - 1);
}
for (int i = 1; i < m - 1; i++) {
dfs(board, 0, i);
dfs(board, n - 1, i);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 'A') {
board[i][j] = 'O';
} else if (board[i][j] == 'O') {
board[i][j] = 'X';
}
}
}
}
};
法二:广度优先搜索
class Solution {
public:
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};
void solve(vector<vector<char>>& board) {
int n = board.size();
if (n == 0) {
return;
}
int m = board[0].size();
queue<pair<int, int>> que;
for (int i = 0; i < n; i++) {
if (board[i][0] == 'O') {
que.emplace(i, 0);
board[i][0] = 'A';
}
if (board[i][m - 1] == 'O') {
que.emplace(i, m - 1);
board[i][m - 1] = 'A';
}
}
for (int i = 1; i < m - 1; i++) {
if (board[0][i] == 'O') {
que.emplace(0, i);
board[0][i] = 'A';
}
if (board[n - 1][i] == 'O') {
que.emplace(n - 1, i);
board[n - 1][i] = 'A';
}
}
while (!que.empty()) {
int x = que.front().first, y = que.front().second;
que.pop();
for (int i = 0; i < 4; i++) {
int mx = x + dx[i], my = y + dy[i];
if (mx < 0 || my < 0 || mx >= n || my >= m || board[mx][my] != 'O') {
continue;
}
que.emplace(mx, my);
board[mx][my] = 'A';
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (board[i][j] == 'A') {
board[i][j] = 'O';
} else if (board[i][j] == 'O') {
board[i][j] = 'X';
}
}
}
}
};
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
for (int i = 0; i < cost.size(); i++) {
int rest = gas[i] - cost[i]; // 记录剩余油量
int index = (i + 1) % cost.size();
while (rest > 0 && index != i) { // 模拟以i为起点行驶一圈
rest += gas[index] - cost[index];
index = (index + 1) % cost.size();
}
// 如果以i为起点跑一圈,剩余油量>=0,返回该起始位置
if (rest >= 0 && index == i) return i;
}
return -1;
}
};
法二:贪心
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int curSum = 0;
int totalSum = 0;
int start = 0;
for (int i = 0; i < gas.size(); i++) {
curSum += gas[i] - cost[i];
totalSum += gas[i] - cost[i];
if (curSum < 0) { // 当前累加rest[i]和 curSum一旦小于0
start = i + 1; // 起始位置更新为i+1
curSum = 0; // curSum从0开始
}
}
if (totalSum < 0) return -1; // 说明怎么走都不可能跑一圈了
return start;
}
};
class Solution {
public:
int candy(vector<int>& ratings) {
int n = ratings.size();
vector<int> left(n);
for (int i = 0; i < n; i++) {
if (i > 0 && ratings[i] > ratings[i - 1]) {
left[i] = left[i - 1] + 1;
} else {
left[i] = 1;
}
}
int right = 0, ret = 0;
for (int i = n - 1; i >= 0; i--) {
if (i < n - 1 && ratings[i] > ratings[i + 1]) {
right++;
} else {
right = 1;
}
ret += max(left[i], right);
}
return ret;
}
};
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ret = 0;
for (auto e: nums) ret ^= e;
return ret;
}
};
https://leetcode-cn.com/problems/single-number-ii/solution/ti-yi-lei-jie-wei-yun-suan-yi-wen-dai-ni-50dc/
法一:哈希表
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_map<int, int> freq;
for (int num: nums) {
++freq[num];
}
int ans = 0;
for (auto [num, occ]: freq) {
if (occ == 1) {
ans = num;
break;
}
}
return ans;
}
};
法二:位运算
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res = 0;
for (int i = 0; i < 32; i++) { // 因为nums[i]是32位整数,
// 所以针对每一位的对应二进制数值求和
int sum = 0;
for (int num : nums) {
sum += ((num >> i) & 1); // 提取从右往左数第i位的数值,将所有nums[i]
// 二进制下的第i位数值进行求和
}
if (sum % 3 == 1) { // 如果没办法被3整除,那么说明落单的那个数的第i位是1不是0
res |= (1 << i);
}
}
return res; // 输出结果
}
};
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for (int i = 0; i < tokens.size(); i++) {
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
int num1 = st.top();
st.pop();
int num2 = st.top();
st.pop();
if (tokens[i] == "+") st.push(num2 + num1);
if (tokens[i] == "-") st.push(num2 - num1);
if (tokens[i] == "*") st.push(num2 * num1);
if (tokens[i] == "/") st.push(num2 / num1);
} else {
st.push(stoi(tokens[i]));
}
}
int result = st.top();
st.pop(); // 把栈里最后一个元素弹出(其实不弹出也没事)
return result;
}
};
https://leetcode-cn.com/problems/maximum-product-subarray/solution/cheng-ji-zui-da-zi-shu-zu-by-leetcode-solution/
法一:
class Solution {
public:
int maxProduct(vector<int>& nums) {
vector <int> maxF(nums), minF(nums);
for (int i = 1; i < nums.size(); ++i) {
maxF[i] = max(maxF[i - 1] * nums[i], max(nums[i], minF[i - 1] * nums[i]));
minF[i] = min(minF[i - 1] * nums[i], min(nums[i], maxF[i - 1] * nums[i]));
}
return *max_element(maxF.begin(), maxF.end());
}
};
法二:空间优化
class Solution {
public:
int maxProduct(vector<int>& nums) {
int maxF = nums[0], minF = nums[0], ans = nums[0];
for (int i = 1; i < nums.size(); ++i) {
int mx = maxF, mn = minF;
maxF = max(mx * nums[i], max(nums[i], mn * nums[i]));
minF = min(mn * nums[i], min(nums[i], mx * nums[i]));
ans = max(maxF, ans);
}
return ans;
}
};
class Solution {
public:
int findMin(vector<int>& nums) {
int low = 0;
int high = nums.size() - 1;
while (low < high) {
int pivot = low + (high - low) / 2;
if (nums[pivot] < nums[high]) {
high = pivot;
}
else {
low = pivot + 1;
}
}
return nums[low];
}
};
https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/solution/xun-zhao-xuan-zhuan-pai-xu-shu-zu-zhong-de-zui–16/
二分查找
class Solution {
public:
int findMin(vector<int>& nums) {
int low = 0;
int high = nums.size() - 1;
while (low < high) {
int pivot = low + (high - low) / 2;
if (nums[pivot] < nums[high]) {
high = pivot;
}
else if (nums[pivot] > nums[high]) {
low = pivot + 1;
}
else {
high -= 1;
}
}
return nums[low];
}
};
class Solution {
public:
int findPeakElement(vector<int>& nums) {
return max_element(nums.begin(), nums.end()) - nums.begin();
}
};
法二:二分查找
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
while( l < r)
{
int mid = ( l + r )/2;
if(nums[mid] > nums[mid + 1]) r = mid;
else l = mid + 1;
}
return r;
}
};
https://leetcode-cn.com/problems/maximum-gap/solution/c-ji-shu-pai-xu-guan-fang-dai-ma-zhu-shi-by-lljj54/
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
//如果数组元素个数小于 2,则返回 0
if(n < 2)
{
return 0;
}
vector<int> buf(n); //buf为临时顺组,用于存储每次排完序的数组
int maxVal = *max_element(nums.begin(), nums.end());
int time = maxBit(maxVal); //计算出需要最高位数,即需要排多少次
int dev = 1;
//开始从低位到高位基数排序
for(int i = 0; i < time; i++){
vector<int> count(10); //桶
//统计每个桶中有多少个数
for(int j = 0; j < n; j++){
int digit = (nums[j] / dev) % 10; //digit 为nums[j]的第i位数
count[digit] ++;
}
//此步是将count[j]由原本表示每个桶的数量,变为表示在数组中的索引
for(int j = 1; j < 10; j++){
count[j] += count[j - 1];
}
//此步对nums按照低位大小进行排序,(count[digit] - 1)表示排序后nums[j]应该在的位置
for(int j = n - 1; j >= 0; j--){
int digit = (nums[j] / dev) % 10;
buf[count[digit] - 1] = nums[j];
count[digit] --;
}
//将临时数组拷贝给nums
copy(buf.begin(),buf.end(), nums.begin());
dev *= 10;
}
//找到相邻元素最大差值
int ret = 0;
for (int i = 1; i < n; i++) {
ret = max(ret, nums[i] - nums[i - 1]);
}
return ret;
}
int maxBit(int maxVal){
int p = 10;
int d = 1;
while(maxVal >= p){
p *= 10;
d++;
}
return d;
}
};
class Solution {
public int calculateMinimumHP(int[][] dungeon) {
// 反向DP
// 状态定义:dp[i][j]表示从[i,j]到终点需要的最小血量,dp[0][0]就是最小初始血量
// 状态转移:1. 如果dungeon[i][j] == 0,那么,dp[i][j] = min(dp[i+1][j], dp[i][j+1])
// 2. 如果dungeon[i][j] < 0,那么,dp[i][j] = min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j]
// 3. 如果dungeon[i][j] > 0,那么,dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j])
// 所以,三种情况可以统一成一种dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j])
// 处理边界:dp[m-1][n-1] = max(1, 1-dungeon[m-1][n-1]),右边和下边,相临的元素只有一个,特殊处理一下。
int m=dungeon.size();
int n=dungeon[0].size();
vector<vector<int>> dp(m, vector<int>(n));
for(int i=m-1;i>=0;i--){
for(int j=n-1;j>=0;j--){
if(i==m-1&&j==n-1){
dp[i][j]=max(1,1-dungeon[m-1][n-1]);
}else if(i==m-1){
dp[i][j]=max(1,dp[i][j+1]-dungeon[i][j]);
}else if(j==n-1){
dp[i][j]=max(1,dp[i+1][j]-dungeon[i][j]);
}else{
dp[i][j]=max(1,min(dp[i+1][j],dp[i][j+1])-dungeon[i][j]);
}
}
}
return dp[0][0];
}
};
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
vector<int> newArr(n);
for (int i = 0; i < n; ++i) {
newArr[(i + k) % n] = nums[i];
}
nums.assign(newArr.begin(), newArr.end());
}
};
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k = k % n;
int count = gcd(k, n);
for (int start = 0; start < count; ++start) {
int current = start;
int prev = nums[start];
do {
int next = (current + k) % n;
swap(nums[next], prev);
current = next;
} while (start != current);
}
}
};
class Solution {
public:
void reverse(vector<int>& nums, int start, int end) {
while (start < end) {
swap(nums[start], nums[end]);
start += 1;
end -= 1;
}
}
void rotate(vector<int>& nums, int k) {
k %= nums.size();
reverse(nums, 0, nums.size() - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.size() - 1);
}
};