25.6.17学习总结
32. 最长有效括号https://leetcode.cn/problems/longest-valid-parentheses/
typedef struct {char a[30005];int index[30005];int top, index_top;
} stack;
int longestValidParentheses(char* s) {int mark[30005] = {0};stack A;A.top = 0, A.index_top = 0;int num = 0, num_temp = 0, i;for (i = 0; * (s + i) != '\0'; i++) {if (*(s + i) == '(') {A.a[A.top++] = '(';A.index[A.index_top++] = i;} else {if (A.top > 0 && A.a[A.top - 1] == '(') {A.top--;mark[A.index[(A.index_top--) - 1]] = 1;mark[i] = 1;}}}for (int j = 0; j < i; j++) {if (mark[j] == 1)num_temp++;else {if (num_temp > num)num = num_temp;num_temp = 0;}}if (num_temp > num)num = num_temp;return num;
}
1. 栈辅助匹配括号对
-
使用栈记录未匹配的左括号
'('
的位置及其索引。 -
当遇到左括号时,将其压入栈
a
,并记录其索引到index
数组中。 -
当遇到右括号
')'
时,检查栈是否非空且栈顶是左括号:-
若匹配成功,弹出栈顶的左括号,并标记该左括号和当前右括号的位置为有效(在
mark
数组中标记为1
)。
-
2. 标记有效位置
-
通过栈操作,所有匹配成功的括号对的位置会被标记为
1
,无效的位置保持为0
。
3. 统计最长连续有效长度
-
遍历
mark
数组,统计连续为1
的最大长度,即为最长有效括号子串的长度。
8. 字符串转换整数 (atoi)https://leetcode.cn/problems/string-to-integer-atoi/
int myAtoi(char* s) {int length = strlen(s), q = 0, flag = 0;while (q < length && s[q] == ' ')q++;if (q < length && (s[q] == '-' || s[q] == '+')) {flag = (s[q] == '+') ? 0 : 1;q++;}long long int a = 0;while (q < length && s[q] >= '0' && s[q] <= '9') {if (a > (INT_MAX - (s[q] - '0')) / 10)return flag ? INT_MIN : INT_MAX;a = a * 10 + s[q] - '0';q++;}return flag ? -a : a;
}
-
使用
long long int
类型的变量a
作为中间结果,避免在计算过程中溢出。 -
溢出检查 :在每次将新数字字符加入
a
之前,检查是否会导致a
超过INT_MAX
的范围。-
如果
a > (INT_MAX - digit) / 10
,说明再乘以 10 并加上当前数字digit
就会溢出,此时直接返回INT_MIN
或INT_MAX
(根据符号flag
)。
-
-
累加数字 :将当前字符转换为数字后,累加到
a
中。 -
索引后移 :继续处理下一个字符。
5. 最长回文子串https://leetcode.cn/problems/longest-palindromic-substring/
char* longestPalindrome(char* s) {int length = strlen(s);int max = 0, index;for (int i = 0; i < length; i++) {int left = i, right = i;{while (left >= 0 && right < length && s[left] == s[right]) {left--, right++;}} if (right - left - 1 > max) {max = right - left - 1;index = i;}left = i, right = i+1;{while (left >= 0 && right < length && s[left] == s[right]) {left--, right++;}}if (right - left - 1 > max) {max = right - left - 1;index = i;}}int start,end;if(max%2==1){start=index-((max+1)/2-1);end=index+((max+1)/2-1);}else {start=index-(max/2-1);end=index+max/2;}for(int i=start,j=0;i<=end;i++,j++){s[j]=s[i];}s[max]='\0';return s;
}
回文子串的中心可以是单个字符(奇数长度)或两个字符之间的空隙(偶数长度)。代码通过遍历每个字符,分别扩展两种情况:
-
奇数长度回文 :以当前字符
i
为中心,向左右扩展。 -
偶数长度回文 :以当前字符
i
和i+1
之间的空隙为中心,向左右扩展。
每次扩展时,比较左右字符是否相等,直到不再匹配为止。记录扩展后的最大回文长度和对应的中心位置。