跳至主要内容

130. Surrounded Regions

· 閱讀時間約 2 分鐘
/*
* @lc app=leetcode id=130 lang=cpp
*
* [130] Surrounded Regions
*
* https://leetcode.com/problems/surrounded-regions/description/
*
* algorithms
* Medium (41.16%)
* Likes: 9078
* Dislikes: 2037
* Total Accepted: 893.7K
* Total Submissions: 2.1M
* Testcase Example: '[["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]'
*
* You are given an m x n matrix board containing letters 'X' and 'O', capture
* regions that are surrounded:
*
*
* Connect: A cell is connected to adjacent cells horizontally or
* vertically.
* Region: To form a region connect every 'O' cell.
* Surround: The region is surrounded with 'X' cells if you can connect the
* region with 'X' cells and none of the region cells are on the edge of the
* board.
*
*
* To capture a surrounded region, replace all 'O's with 'X's in-place within
* the original board. You do not need to return anything.
*
*
* Example 1:
*
*
* Input: board =
* [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
*
* Output:
* [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
*
* Explanation:
*
* In the above diagram, the bottom region is not captured because it is on the
* edge of the board and cannot be surrounded.
*
*
* Example 2:
*
*
* Input: board = [["X"]]
*
* Output: [["X"]]
*
*
*
* Constraints:
*
*
* m == board.length
* n == board[i].length
* 1 <= m, n <= 200
* board[i][j] is 'X' or 'O'.
*
*
*/

// @lc code=start
class Solution {
public:
void solve(vector<vector<char>>& board)
{
int rows = board.size(), cols = board[0].size();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (board[i][j] == 'O' && (i == 0 || j == 0 || i == rows - 1 || j == cols - 1))
{
dfs(board, i, j);
}
}
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == '#') board[i][j] = 'O';
}
}
}
void dfs(vector<vector<char>>& board, int i, int j)
{
int rows = board.size(), cols = board[0].size();
if (i < 0 || j < 0 || i >= rows || j >= cols || board[i][j] != 'O')
{
return;
}
board[i][j] = '#';
vector<vector<int>> directions = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
for(auto dir : directions)
{
dfs(board, i + dir[0], j + dir[1]);
}
}
};
// @lc code=end
  • T: $O()$
  • S: $O()$

129. Sum Root to Leaf Numbers

· 閱讀時間約 1 分鐘

DFS

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int sumNumbers(TreeNode* root)
{
return dfs(root, 0);
}
int dfs(TreeNode* root, int sum)
{
if (!root) return 0;
sum = sum * 10 + root->val;
if (!root->left && !root->right) return sum;
return dfs(root->left, sum) + dfs(root->right, sum);
}
};
  • T: $O(n)$
  • S: $O(H)$

128. Longest Consecutive Sequence

· 閱讀時間約 1 分鐘
class Solution {
public:
int longestConsecutive(vector<int>& nums)
{
unordered_set<int> st(nums.begin(), nums.end());
int res = 0;
for(auto& num : nums)
{
// 如果是連續數字的話,避免重複計算
if(st.count(num - 1)) continue;

int cur = num;
int length = 1;
while(st.count(cur + 1))
{
++cur; ++length;
}
res = max(res, length);
}
return res;
}
};
  • T: $O(N)$
  • S: $O(N)$

125. Valid Palindrome

· 閱讀時間約 1 分鐘
class Solution {
public:
bool isPalindrome(string s)
{
int left = 0, right = s.size() - 1;
while (left < right)
{
while (left < right && !isalnum(s[left])) ++left;
while (left < right && !isalnum(s[right])) --right;
if (tolower(s[left]) != tolower(s[right])) return false;
++left; --right;
}
return true;
}
};
  • T: $O(N)$
  • S: $O(1)$

123. Best Time to Buy and Sell Stock III

· 閱讀時間約 2 分鐘
/*
* @lc app=leetcode id=123 lang=cpp
*
* [123] Best Time to Buy and Sell Stock III
*
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
*
* algorithms
* Hard (49.51%)
* Likes: 9913
* Dislikes: 201
* Total Accepted: 705K
* Total Submissions: 1.4M
* Testcase Example: '[3,3,5,0,0,3,1,4]'
*
* You are given an array prices where prices[i] is the price of a given stock
* on the i^th day.
*
* Find the maximum profit you can achieve. You may complete at most two
* transactions.
*
* Note: You may not engage in multiple transactions simultaneously (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.
*
*
*
* Constraints:
*
*
* 1 <= prices.length <= 10^5
* 0 <= prices[i] <= 10^5
*
*
*/

// @lc code=start
class Solution {
public:
int maxProfit(vector<int>& prices)
{
int t1minCost = INT_MAX, t2minCost = INT_MAX;
int t1maxProfit = 0, t2maxProfit = 0;

for (int price : prices)
{
t1minCost = min(t1minCost, price);
t1maxProfit = max(t1maxProfit, price - t1minCost);
t2minCost = min(t2minCost, price - t1maxProfit);
t2maxProfit = max(t2maxProfit, price - t2minCost);
}
return t2maxProfit;
}
};
// @lc code=end
  • T: $O(n)$
  • S: $O(1)$

122. Best Time to Buy and Sell Stock II

· 閱讀時間約 2 分鐘
/*
* @lc app=leetcode id=122 lang=cpp
*
* [122] Best Time to Buy and Sell Stock II
*
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/
*
* algorithms
* Medium (68.04%)
* Likes: 14056
* Dislikes: 2738
* Total Accepted: 2.3M
* Total Submissions: 3.3M
* Testcase Example: '[7,1,5,3,6,4]'
*
* You are given an integer array prices where prices[i] is the price of a
* given stock on the i^th day.
*
* On each day, you may decide to buy and/or sell the stock. You can only hold
* at most one share of the stock at any time. However, you can buy it then
* immediately sell it on the same day.
*
* Find and return the maximum profit you can achieve.
*
*
* Example 1:
*
*
* Input: prices = [7,1,5,3,6,4]
* Output: 7
* Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit
* = 5-1 = 4.
* Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 =
* 3.
* Total profit is 4 + 3 = 7.
*
*
* 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.
* Total profit is 4.
*
*
* Example 3:
*
*
* Input: prices = [7,6,4,3,1]
* Output: 0
* Explanation: There is no way to make a positive profit, so we never buy the
* stock to achieve the maximum profit of 0.
*
*
*
* Constraints:
*
*
* 1 <= prices.length <= 3 * 10^4
* 0 <= prices[i] <= 10^4
*
*
*/

// @lc code=start
class Solution {
public:
int maxProfit(vector<int>& prices)
{
int maxProfit = 0;
for (int i = 1; i < prices.size(); ++i)
{
if (prices[i] > prices[i - 1])
{
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
};
// @lc code=end
  • T: $O(N)$
  • S: $O(1)$

121. Best Time to Buy and Sell Stock

· 閱讀時間約 2 分鐘
/*
* @lc app=leetcode id=121 lang=cpp
*
* [121] Best Time to Buy and Sell Stock
*
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/
*
* algorithms
* Easy (54.33%)
* Likes: 32079
* Dislikes: 1225
* Total Accepted: 5.6M
* Total Submissions: 10.4M
* Testcase Example: '[7,1,5,3,6,4]'
*
* You are given an array prices where prices[i] is the price of a given stock
* on the i^th 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 <= 10^5
* 0 <= prices[i] <= 10^4
*
*
*/

// @lc code=start
class Solution {
public:
int maxProfit(vector<int>& prices)
{
int minCost = INT_MAX, maxProfit = 0;
for (int price : prices)
{
minCost = min(price, minCost);
maxProfit = max(maxProfit, price - minCost);
}
return maxProfit;
}
};
// @lc code=end
  • T: $O(N)$
  • S: $O(1)$

120. Triangle

· 閱讀時間約 2 分鐘
/*
* @lc app=leetcode id=120 lang=cpp
*
* [120] Triangle
*
* https://leetcode.com/problems/triangle/description/
*
* algorithms
* Medium (57.96%)
* Likes: 9775
* Dislikes: 567
* Total Accepted: 890K
* Total Submissions: 1.5M
* Testcase Example: '[[2],[3,4],[6,5,7],[4,1,8,3]]'
*
* Given a triangle array, return the minimum path sum from top to bottom.
*
* For each step, you may move to an adjacent number of the row below. More
* formally, if you are on index i on the current row, you may move to either
* index i or index i + 1 on the next row.
*
*
* Example 1:
*
*
* Input: triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
* Output: 11
* Explanation: The triangle looks like:
* ⁠ 2
* ⁠ 3 4
* ⁠6 5 7
* 4 1 8 3
* The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined
* above).
*
*
* Example 2:
*
*
* Input: triangle = [[-10]]
* Output: -10
*
*
*
* Constraints:
*
*
* 1 <= triangle.length <= 200
* triangle[0].length == 1
* triangle[i].length == triangle[i - 1].length + 1
* -10^4 <= triangle[i][j] <= 10^4
*
*
*
* Follow up: Could you do this using only O(n) extra space, where n is the
* total number of rows in the triangle?
*/

// @lc code=start
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle)
{
int n = triangle.size();
vector<int> dp = triangle.back();
for (int i = n - 2; i >= 0; i--)
{
for (int j = 0; j <= i; j++)
{
dp[j] = triangle[i][j] + min(dp[j], dp[j + 1]);
}
}
return dp[0];
}
};
// @lc code=end
  • T: $O(N^2)$
  • S: $O(N)$

117. Populating Next Right Pointers in Each Node II

· 閱讀時間約 2 分鐘

Recursion

/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;

Node() : val(0), left(NULL), right(NULL), next(NULL) {}

Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
Node* connect(Node* root)
{
if (!root) return nullptr;
// 使用一個指標指向下一個節點
Node* cur = root->next;

while (cur)
{
if (cur->left)
{
cur = cur->left;
break;
}
if (cur->right)
{
cur = cur->right;
break;
}
cur = cur->next;
}

if (root->right)
{
root->right->next = cur;
}
if (root->left)
{
root->left->next = root->right ? root->right : cur;
}
connect(root->right);
connect(root->left);
return root;
}
};
  • T: $O(n)$

  • S: $O(n)$

  • Iteration

/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;

Node() : val(0), left(NULL), right(NULL), next(NULL) {}

Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
Node* connect(Node* root)
{
if (!root) return nullptr;

queue<Node*> q{{root}};

while (!q.empty())
{
int qSize = q.size();
for (int i = 0; i < qSize; i++)
{
Node* node = q.front(); q.pop();
if (i < qSize - 1)
{
// 如果不是最末端的 node,node->next 指到下一個節點
node->next = q.front();
}

if (node->left) q.push(node->left);
if (node->right) q.push(node->right);

}
}
return root;
}
};
  • T: $O(n)$

  • S: $O(n)$

  • Space O(1)

/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;

Node() : val(0), left(NULL), right(NULL), next(NULL) {}

Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
Node* connect(Node* root) {
Node* dummy = new Node(-1);
Node* cur = dummy;
Node* head = root;

while (root)
{
if (root->left)
{
cur->next = root->left;
cur = cur->next;
}
if (root->right)
{
cur->next = root->right;
cur = cur->next;
}

root = root->next;

if (!root)
{
cur = dummy;
root = dummy->next;
dummy->next = NULL;
}
}
return head;
}
};
  • T: $O(n)$
  • S: $O(1)$