题号 | 题目 | 说明 |
3 | Longest Substring Without Repeating Characters | 最长无重复字符的子串 |
8 | String to Integer (atoi) | 字符串转为整数 |
58 | Length of Last Word | 求末尾单词的长度 |
76 | Minimum Window Substring | 最小窗口子串 |
344 | Reverse String | 翻转字符串 |
3. Longest Substring Without Repeating Characters 最长无重复字符的子串
维护了一个滑动窗口,窗口内的都是没有重复的字符,只关心每个字符最后出现的位置,并建立映射。窗口的右边界是当前遍历到的字符的位置,left来指向滑动窗口的左边界
建立一个256位大小的整型数组来代替HashMap,全部初始化为-1,这样的好处是我们就不用像之前的HashMap一样要查找当前字符是否存在映射对了,对于每一个遍历到的字符,我们直接用其在数组中的值来更新left,因为默认是-1,而left初始化也是-1,所以并不会产生错误,这样就省了if判断的步骤
- 一个256个单元的数组,每一个单元代表一个字符,数组中保存上次该字符上次出现的位置;
- 依次读入字符串,同时维护数组的值;
- 如果遇到冲突了,就返回冲突字符中保存的位置,继续第二步。
func lengthOfLongestSubstring(s string) int {
var m = make(map[byte]int)
var res, left = 0, -1
for i := 0; i < len(s); i++ {
val, ok := m[s[i]]
if ok && left < val {
left = val
}
m[s[i]] = i
if i-left > res {
res = i - left
}
}
return res
}
8. String to Integer (atoi)
1. 若字符串开头是空格,则跳过所有空格,到第一个非空格字符,如果没有,则返回0.
2. 若第一个非空格字符是符号+/-,则标记sign的真假
3. 若下一个字符不是数字,则返回0. 完全不考虑小数点和自然数的情况,不过这样也好,起码省事了不少。
4. 如果下一个字符是数字,则转为整形存下来,若接下来再有非数字出现,则返回目前的结果。
5. 还需要考虑边界问题,如果超过了整形数的范围,则用边界值替代当前值。
28. [LeetCode] Implement strStr()
Implement strStr().
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Example 1:
Input: haystack = "hello", needle = "ll" Output: 2
Example 2:
Input: haystack = "aaaaa", needle = "bba" Output: -1
首先要做一些判断,如果子字符串为空,则返回0,如果子字符串长度大于母字符串长度,则返回-1。然后我们开始遍历母字符串,我们并不需要遍历整个母字符串,而是遍历到剩下的长度和子字符串相等的位置即可,这样可以提高运算效率。然后对于每一个字符,我们都遍历一遍子字符串,一个一个字符的对应比较,如果对应位置有不等的,则跳出循环,如果一直都没有跳出循环,则说明子字符串出现了,则返回起始位置即可.
char *strStr(char *haystack, char *needle) {
string str1(haystack);
int m=str1.size(); //母字符串长度
string str2(needle);
int n=str2.size(); //子字符串长度
if(m<n) return NULL;
int i,j;
for(i=0;i<=m-n;i++)
{
for(j=0;j<n;j++)
{
if(str1[i+j] != str2[j]) break;
}
if(j==n)
return haystack+i; //字符串指针指向首字符;
}
return NULL;
}
58. Length of Last Word 求末尾单词的长度
从字符串末尾开始,先将末尾的空格都去掉,然后开始找非空格的字符的长度即可
func lengthOfLastWord(s string) int {
var right, res = len(s) - 1, 0
for right>=0 && s[right] == ' ' {right--}
for right>=0 && s[right] != ' ' {
right--
res++
}
return res
}
76. Minimum Window Substring 最小窗口子串
当cnt和T串字母个数相等时,说明此时的窗口已经包含了T串中的所有字母,此时更新一个minLen和结果res
开始收缩左边界,由于我们遍历的时候,对映射值减了1,所以此时去除字母的时候,就要把减去的1加回来,此时如果加1后的值大于0了,说明此时我们少了一个T中的字母,那么cnt值就要减1了,然后移动左边界left。
func minWindow(s string, t string) string {
var res, m = "", make(map[byte]int)
var left, cnt, minLen = 0, 0, len(s) + 1
for i:=0; i<len(t); i++ {m[t[i]]++}
for i:=0; i<len(s); i++ {
if _, ok := m[s[i]]; ok {
m[s[i]]--
if m[s[i]] >= 0 {cnt++}
}
for cnt == len(t) {
if minLen > i - left + 1 {
minLen = i - left + 1
res = s[left:minLen+left]
}
if _, ok := m[s[left]]; ok {
m[s[left]]++
if m[s[left]] > 0 {cnt--}
}
left++
}
}
return res
}
344. [LeetCode] Reverse String 翻转字符串
从两头往中间走,同时交换两边的字符即可
class Solution {
public:
string reverseString(string s) {
int left = 0, right = s.size() - 1;
while (left < right) {
char t = s[left];
s[left++] = s[right];
s[right--] = t;
}
return s;
}
};