跳至主要内容

268 篇文章 含有標籤「leetcode」

檢視所有標籤

8. String to Integer (atoi)

· 閱讀時間約 3 分鐘

Implement the myAtoi(string s) function, which converts a string to a 32-bit signed integer.

The algorithm for myAtoi(string s) is as follows:

  1. Whitespace: Ignore any leading whitespace (" ").
  2. Signedness: Determine the sign by checking if the next character is '-' or '+', assuming positivity is neither present.
  3. Conversion: Read the integer by skipping leading zeros until a non-digit character is encountered or the end of the string is reached. If no digits were read, then the result is 0.
  4. Rounding: If the integer is out of the 32-bit signed integer range [-231, 231 - 1], then round the integer to remain in the range. Specifically, integers less than -231 should be rounded to -231, and integers greater than 231 - 1 should be rounded to 231 - 1.

Return the integer as the final result.

Example 1:

Input: s = "42"

Output: 42

Explanation:

The underlined characters are what is read in and the caret is the current reader position. Step 1: "42" (no characters read because there is no leading whitespace) ^ Step 2: "42" (no characters read because there is neither a '-' nor '+') ^ Step 3: "42" ("42" is read in) ^

Example 2:

Input: s = " -042"

Output: -42

Explanation:

Step 1: " -042" (leading whitespace is read and ignored) ^ Step 2: " -042" ('-' is read, so the result should be negative) ^ Step 3: " -042" ("042" is read in, leading zeros ignored in the result) ^

Example 3:

Input: s = "1337c0d3"

Output: 1337

Explanation:

Step 1: "1337c0d3" (no characters read because there is no leading whitespace) ^ Step 2: "1337c0d3" (no characters read because there is neither a '-' nor '+') ^ Step 3: "1337c0d3" ("1337" is read in; reading stops because the next character is a non-digit) ^

Example 4:

Input: s = "0-1"

Output: 0

Explanation:

Step 1: "0-1" (no characters read because there is no leading whitespace) ^ Step 2: "0-1" (no characters read because there is neither a '-' nor '+') ^ Step 3: "0-1" ("0" is read in; reading stops because the next character is a non-digit) ^

Example 5:

Input: s = "words and 987"

Output: 0

Explanation:

Reading stops at the first non-digit character 'w'.

Constraints:

  • 0 <= s.length <= 200
  • s consists of English letters (lower-case and upper-case), digits (0-9), ' ', '+', '-', and '.'.
class Solution {
public:
int myAtoi(string s) {
// 紀錄正負號,預設是正號
int sign = 1;
int res = 0;
int i = 0;
int n = s.size();
// 掃 s,略過空白格
while (i < n && s[i] == ' ') i++;

// 紀錄正負號,i++
if (i < n && s[i] == '+') {
sign = 1;
i++;
} else if (i < n && s[i] == '-') {
sign = -1;
i++;
}
// 現在的 i 就是整數的起始位置
while (i < n && isdigit(s[i])) {
int digit = s[i] - '0';
// 檢查有沒有超過 32-bit signed integer 的範圍
if ((res > INT_MAX / 10) || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
return sign == 1 ? INT_MAX : INT_MIN;
}
// 10 進位
res = 10 * res + digit;
i++;
}
return sign * res;
}
};
  • T: $O(N)$
  • S: $O(1)$

7. Reverse Integer

· 閱讀時間約 1 分鐘

Given a signed 32-bit integer x, return xwith its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range [-231, 231 - 1], then return 0.

Assume the environment does not allow you to store 64-bit integers (signed or unsigned).

Example 1:

Input: x = 123 Output: 321

Example 2:

Input: x = -123 Output: -321

Example 3:

Input: x = 120 Output: 21

Constraints:

  • -231 <= x <= 231 - 1
class Solution {
public:
int reverse(int x) {
int reversed = 0;
while(x != 0) {
int digit = x % 10;
x /= 10;
if(reversed > INT_MAX / 10 || (reversed == INT_MAX / 10 && digit > INT_MAX % 10))
return 0;
if(reversed < INT_MIN / 10 || (reversed == INT_MIN / 10 && digit < INT_MIN % 10))
return 0;
reversed = reversed * 10 + digit;
}
return reversed;
}
};
  • T: $O(\log N)$
  • S: $O(1)$

6. Zigzag Conversion

· 閱讀時間約 1 分鐘
class Solution {
public:
string convert(string s, int numRows) {
// 考慮 base case
if (numRows <= 1) return s;

string res;
int n = s.size();

// 建立一個 vector 儲存字母
vector<string> stringVector(numRows);

int i = 0;
while (i < n) {
// 當 pos 小於 numRows 的時候,將 s[i] 加到 stringVector 裡
// Z 字形,由上往下的部分
for (int pos = 0; pos < numRows && i < n; ++pos) {
stringVector[pos] += s[i];
i++;
}
// pos 從 numRows - 2 遞減,最少到 1
// Z 字形,由下往上的部分
for (int pos = numRows - 2; pos >= 1 && i < n; --pos) {
stringVector[pos] += s[i++];
}
}

// 將字串 join 在一起
for (auto& a : stringVector) {
res += a;
}
return res;
}
};
  • T: $O(numRows \cdot n)$
  • S: $O(numRows \cdot n)$

5. Longest Palindromic Substring

· 閱讀時間約 4 分鐘

Hint - Brute-force

class Solution {
public:
string longestPalindrome(string s)
{
// Start with the longest possible substring and reduce the length until we find a palindrome
for ()
{
// Check all substrings of length 'j'
for ()
{
// If the substring s.substr(i, j) is a palindrome, return it as the result
if ()
{
}
}
}
// If no palindrome is found (which is unlikely since single characters are palindromes), return an empty string
}

// Helper function to check if a given string 's' is a palindrome
bool isPalindrome(string s)
{
// Initialize two pointers at the start and end of the string
// Check characters from both ends moving towards the center
while ()
{
// If characters at pointers do not match, it's not a palindrome
// Move the pointers closer to the center
}
// If all characters matched, the string is a palindrome
}
};
  • Brute-force
class Solution {
public:
string longestPalindrome(string s)
{
int n = s.size();
for (int j = n; j > 0; --j)
{
for (int i = 0; i <= n - j; i++)
{
if (isPalindrome(s.substr(i, j)))
{
return s.substr(i, j);
}
}
}
return "";
}

bool isPalindrome(string s)
{
int i = 0, j = s.size() - 1;
while (i < j)
{
if (s[i] != s[j])
{
return false;
}
++i; --j;
}
return true;
}
};
  • T: $O(N^3)$
  • S: $O(1)$

Hint - Expand From Centers

class Solution {
public:
string longestPalindrome(string s)
{
// Initialize the result string to store the longest palindrome found
// Initialize current length and maximum length of palindrome found

// Iterate over each character in the string as the center of a potential palindrome
for ()
{
// Case 1: Odd length palindrome with center at 'i'
// Expand around the center while characters on both sides are equal
while ()
{
// Calculate current palindrome length
// Update result if a longer palindrome is found
// Move left pointer to the left and right pointer to the right
}

// Case 2: Even length palindrome with centers at 'i' and 'i+1'
// Expand around the centers while characters on both sides are equal
while ()
{
// Calculate current palindrome length
// Update result if a longer palindrome is found
// Move left pointer to the left and right pointer to the right
}
}
// Return the longest palindromic substring found
}
};
  • Expand From Centers
class Solution {
public:
string longestPalindrome(string s)
{
string res = "";
int curLen = 0, maxLen = 0;
for (int i = 0; i < s.size(); ++i)
{
int left = i, right = i;
while (left >= 0 && right < s.size() && s[left] == s[right])
{
curLen = right - left + 1;
if (curLen > maxLen)
{
res = s.substr(left, curLen);
maxLen = curLen;
}
--left; ++right;
}

left = i, right = i + 1;
while (left >= 0 && right < s.size() && s[left] == s[right])
{
curLen = right - left + 1;
if (curLen > maxLen)
{
res = s.substr(left, curLen);
maxLen = curLen;
}
--left; ++right;
}
}
return res;
}
};
  • T: $O(N^2)$
  • S: $O(1)$

Hint - Manacher's Algorithm

class Solution {
public:
string longestPalindrome(string s)
{
// Transform the original string to avoid even-length palindrome issues by inserting '#'
// between every character and at the beginning and end.

// Length of the transformed string

// Array to store the length of the palindrome radius for each center

// Center and radius of the rightmost palindrome found

for ()
{
// Mirror of the current index i with respect to the current center

// If within the bounds of the current known palindrome, use the mirror's palindrome length

// Attempt to expand the palindrome centered at i

// Update the center and radius if the expanded palindrome at i goes beyond the current known radius
}

// Find the longest palindrome in the transformed string

// Calculate the start index of the longest palindrome in the original string

// Return the longest palindrome substring from the original string
}
};
  • Manacher's Algorithm
class Solution {
public:
string longestPalindrome(string s)
{
string t = "#";
for (char c : s)
{
t += c;
t += "#";
}

int n = t.size();

vector<int> p(n, 0);

int center = 0, radius = 0;

for (int i = 0; i < n; i++)
{
int mirror = 2 * center - i;

if (i < radius)
{
p[i] = min(radius - i, p[mirror]);
}

while (i + 1 + p[i] < n && i - 1 - p[i] >= 0 && t[i + 1 + p[i]] == t[i - 1 - p[i]])
{
p[i]++;
}

if (i + p[i] > radius)
{
center = i;
radius = i + p[i];
}
}

int maxLen = 0;
int centerIndex = 0;
for (int i = 0; i < n; i++)
{
if (p[i] > maxLen)
{
maxLen = p[i];
centerIndex = i;
}
}

int startIndex = (centerIndex - maxLen) / 2;

return s.substr(startIndex, maxLen);
}
};
  • T: $O(n)$
  • S: $O(n)$

3. Longest Substring Without Repeating Characters

· 閱讀時間約 1 分鐘
  • 滑動視窗的大小不固定的例子。
  • 搭配 HashMap 儲存滑動視窗的 Index。
  • 初始值:curLen, maxLen, 左右滑動視窗的邊界 ij
  • for loop 移動右邊界 j,如果發現重複的字元,更新左邊界 i
  • curLen = j - i + 1
  • 不斷取最大的 maxLen 值。
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
int curLen = 0, maxLen = 0;

unordered_map<char, int> m;

int left = 0;
for (int right = 0; right < s.size(); ++right)
{
if (m.count(s[right]))
{
// 如果發現重複字元,則更新左邊界
left = max(left, m[s[right]]);
}
curLen = right - left + 1;
maxLen = max(maxLen, curLen);
// 更新右邊界的位置為 right + 1
m[s[right]] = right + 1;
}
return maxLen;
}
};
  • T: $O(N)$
  • S: $O(\min(M, N))$

2. Add Two Numbers

· 閱讀時間約 1 分鐘
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2)
{
ListNode* dummy = new ListNode();
ListNode* cur = dummy;

int carry = 0;
while (l1 || l2 || carry)
{
int v1 = l1 ? l1->val : 0;
int v2 = l2 ? l2->val : 0;

int valSum = v1 + v2 + carry;

carry = valSum / 10;
valSum %= 10;

cur->next = new ListNode(valSum);
cur = cur->next;

l1 = l1 ? l1->next : nullptr;
l2 = l2 ? l2->next : nullptr;
}
return dummy->next;
}
};
- T: $O(\max(M, N))$
- S: $O(1)$

1. Two Sum

· 閱讀時間約 1 分鐘
  • Brute-force
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
int n = nums.size();
for (int i = 0; i < n; ++i)
{
for (int j = i + 1; j < n; ++j)
{
if(nums[i] + nums[j] == target) return {i, j};
}
}
return {};
}
};
  • T: $O(N^2)$

  • S: $O(1)$

  • HashMap

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
int n = nums.size();
unordered_map<int, int> m;
for (int i = 0; i < n; ++i)
{
int complement = target - nums[i];

if (m.count(complement)) return {i, m[complement]};

m[nums[i]] = i;
}
return {};
}
};
  • T: $O(N)$
  • S: $O(N)$