Day8 字符串

42 阅读2分钟

字符串算法总结

emm 字符串算法部分 略微有点简单 涉及kmp的最后两题 没去深究 没有学习kmp算法 使用了其他方法解决

反转字符串

  • leetcode.cn/problems/re…

  • 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

  • leetcode.cn/problems/re…

  • 其实就是一个简单的模拟过程 ,但是我总是在循环过程时忘记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("")
    };
    

替换空格

  • leetcode.cn/problems/ti…

  • emm 直接split 然后再join了 哈哈哈哈。如果不使用额外的辅助空间,就是数组的扩充,也就是双指针的算法。

  • 其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

    这么做有两个好处:

    1. 不用申请新数组。
    2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
  • 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("")
    
    }
    

反转字符串中的单词

  • leetcode.cn/problems/re…

  • 首先想到的肯定是简单的调用库函数

  • 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('');
    

左旋字符串

  • leetcode.cn/problems/zu…

  • 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('')
    };
    

找出字符串中第一个匹配的下标值

  • leetcode.cn/problems/fi…

  • 直接双循环了。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
    
    };
    

重复的子字符串

  • leetcode.cn/problems/re…

  • 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
    };