字符串算法总结
emm 字符串算法部分 略微有点简单 涉及kmp的最后两题 没去深究 没有学习kmp算法 使用了其他方法解决
反转字符串
-
var reverseString = function(s) { let left = 0 let right = s.length - 1 for(let i = left , j = right ; i < j ; i++ , j--){ [s[i],s[j]] = [ s[j], s[i]] } return s };
反转字符串2
-
其实就是一个简单的模拟过程 ,但是我总是在循环过程时忘记left++ right--这种错误!下次注意
-
var reverseStr = function(s, k) { function reverse(arr,left,right){ while(left < right){ let temp = arr[left] arr[left] = arr[right] arr[right] = temp left++ right-- } } let arr = s.split("") let len = arr.length for(let i = 0 ; i < len ; i += k*2) { let left = i let right = Math.min(i + k ,len) - 1 reverse(arr,left , right) } return arr.join("") };
替换空格
-
emm 直接split 然后再join了 哈哈哈哈。如果不使用额外的辅助空间,就是数组的扩充,也就是双指针的算法。
-
其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
-
var replaceSpace = function(s) { let arr = s.split("") let len = arr.length let len1 = 0 for(let item of arr){ if(item === " ") len1++ } let left = len - 1 let right = left + len1 * 2 while(left >= 0) { if(arr[left]!==" "){ arr[right] = arr[left] left-- right-- }else{ arr[right--] = "0" arr[right--] = "2" arr[right--] = "%" left -- } } return arr.join("") }
反转字符串中的单词
-
首先想到的肯定是简单的调用库函数
-
var reverseWords = function(s) { let newS = s.trim().split(" ") newS.reverse() return newS.filter(item =>item!=="").join(" ") };
-
还是不使用辅助空间,删除空格的办法就是 双指针 填充数组 ,但是切记切记 填充完之后要重赋值数组的长度!!!!!!删除首尾的空格可以使用trim函数
-
// 删除多余空格 function removeExtraSpaces(strArr) { let slowIndex = 0; let fastIndex = 0; while(fastIndex < strArr.length) { // 移除开始位置和重复的空格 if (strArr[fastIndex] === ' ' && (fastIndex === 0 || strArr[fastIndex - 1] === ' ')) { fastIndex++; } else { strArr[slowIndex++] = strArr[fastIndex++]; } } // 移除末尾空格 strArr.length = strArr[slowIndex - 1] === ' ' ? slowIndex - 1 : slowIndex; }
-
var reverseWords = function(s) { const arr = s.trim().split("") removeSpace(arr) console.log(arr) reverse(arr, 0, arr.length - 1); let start = 0; for(let i = 0; i <= arr.length; i++) { if (arr[i] === ' ' || i === arr.length) { // 翻转单词 reverse(arr, start, i - 1); start = i + 1; } } function removeSpace(arr) { let slow = 0 let fast = 0 while(fast < arr.length) { if(arr[fast] === " "&& arr[fast - 1] === " "){ fast ++ }else{ arr[slow++] = arr[fast++] } } arr.length = slow } function reverse(strArr, start, end) { let left = start; let right = end; while(left < right) { // 交换 [strArr[left], strArr[right]] = [strArr[right], strArr[left]]; left++; right--; } } return arr.join('');
左旋字符串
-
var reverseLeftWords = function(s, n) { return s.slice(n)+s.slice(0,n) };
-
两种方法 一个是三次reverse 一个是先补充字符串长度 然后再截取
-
var reverseLeftWords = function(s, n) { const length = s.length; let i = 0; while (i < length - n) { //length长度不变,s在变大 s = s[length - 1] + s; i++; } return s.slice(0, length); }; var reverseLeftWords = function(s, n) { function reverseWords(strArr, start, end) { let temp; while (start < end) { temp = strArr[start]; strArr[start] = strArr[end]; strArr[end] = temp; start++; end--; } } let strArr = s.split(''); let length = strArr.length; reverseWords(strArr, 0, length - 1); reverseWords(strArr,0,length-n-1) reverseWords(strArr,length-n,length-1) return strArr.join('') };
找出字符串中第一个匹配的下标值
-
直接双循环了。kmp没看
-
var strStr = function(haystack, needle) { let len1 = haystack.length let len2 = needle.length for(let i = 0 ; i + len2 <= len1 ; i++) { let flag = true for(let j = 0 ; j < len2 ; j++) { if(haystack[i + j] !== needle[j]){ flag = false break } } if(flag) { return i } } return -1 };
重复的子字符串
-
substr(start, length) substring(start,end+1)
-
var repeatedSubstringPattern = function(s) { for(let i = 1 ; i <= Math.floor(s.length / 2) ; i++){ let sub = s.substring(0,i) if(s.length%i === 0){ if(sub.repeat(s.length / i) === s ) return true } } return false };