算法练习-数组和字符串Ⅰ

189 阅读2分钟

二分查找

当数组有序的时候遍历查找有点浪费性能,我们可以借助其有序性来减少比较次数,降低时间复杂度,所谓二分查找,就是取一个数组中间的值,将其和目标值对比,如果相等则返回其索引,如果目标值大于它,那么我们再从这个数右边来进行相同的操作(反之从左边进行相同的操作),如果最后查找完依然没找到则返回-1

    var arr=[1,2,3,4,5,6]
    function binSearch(arr,target){
        let start = 0
        let end = arr.length-1
        while(start<=end){
            var mid = Math.floor((start+end)/2)
            if(arr[mid]===target){return mid}
            else if(target<arr[mid]){end=mid-1}
            else{start = mid+1}
        }
        return -1
    }
    console.log(binSearch(arr,4))

最长相同元素子串

比如 'aabbbbccccccccc' 最长为c,长度为9 采用滑动窗口,相同元素的化,右指针向右移动,count+1,遇到不同的count置为0,left置为当前索引

    var str = 'aabbbbccccccccc'
    function maxLengthSubstr(str){
        let count=0
        let max=0
        let left=0
        let right=0
        if(str.length==0) return 0
        if(str.length==1) return 1
        while(right!==str.length){
            while(str[left]===str[right]){
                count++
                right++
            }
            max=Math.max(max,count)
            count=0
            left=right
        }
        return max
    }
    console.log(maxLengthSubstr(str))

数组中重复的数字

在一个长度为n的数组nums里的所有数字都在0~n-1的范围内,数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次,清找出任意一个重复的数字 哈希表解法

    var nums=[1,2,1,3]
    function findRepeadtNumber(nums){
        const map = new Map()
        for(let i=0;i<nums.length;i++){
            if(map.get(nums[i])===0) return nums[i]
            else{map.set(nums[i],0)}
        }
        return false
        
    }
    console.log(findRepeadtNumber(nums))

连续子数组的最大和

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组,求所有子数组的和的最大值 动态规划解法

    function maxSubArray(nums){
        let pre=0
        let maxAns=nums[0]
        nums.forEach(item=>{
            pre = Math.max(pre+item,item)
            maxAns = Math.max(pre,maxAns)
        })
        return maxAns
    }

在排序数组中查找数字

统计一个数字在一个排序数组中的出现的次数 暴力:遍历+hashmap,如果最后才出现这个数字,那么需要全部遍历一遍 我们得运用好这个排序的条件 解题思路:由于是有序数组,我们可以通过二分查找先找到指定数字的索引,然后使用两个指针分别从这个索引向前向后遍历,一旦遇到和自己不同的就退出遍历

    function search(nums,target){
        var index = binSearch(nums,target)
        if(index == -1) return 0
        else{
            let count=1//找到之后本身就算一次
            for(let i=index+1;i<nums.length;i++){
                if(nums[i]===nums[index]){count++}
                else{break}
            }
            for(let i=index-1;i>=0;i--){
                if(nums[i]===nums[index]){count++}
                else{break}
            }
            return count
        }
        
        
    }
    function binSearch(nums,target){
        var start=0
        var end=nums.length-1
        
        while(start<=end){
            var mid = Math.floor((start+end)/2)
            if(target==nums[mid]){return mid}
            else if(target<nums[mid]){end=mid-1}
            else{start = mid +1}
        }
        return -1
    }
    
    var nums=[1,1,2,2,3,4,5,5,6,6,6,7,8,9]
    console.log(search(nums,6))

翻转单词顺序

比如'banana apple pear'翻转为'pear apple banana' 可以用双指针一个指针控制单词内部的移动,一个控制单词个数的移动

    function reverseWord(str){
        let p,q,res=[]//p控制单词内部指针移动,q控制不同单词
        //去除首位的空格
        str=str.trim()
        p=q=str.length-1
        while(p>=0){
            while(p>=0&&str[p]!=' '){//p不为空格的时候操作
                if(str[p-1]===' '||p==0){
                    res.push(str.substring(p,q+1))
                }
                p--
            }
         while(p>=0&&str[p]===' '){//p指向空格的操作
             p--
             q=p
         }
        }
        return res.join(' ')
    }

左旋转字符串

字符串的左旋转操作时把字符串前面的若干个字符串转义到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串“abcdefg”和数字2,该函数将返回左旋转两位得到的结果“cdefgab”

    function reverseLeftWords(str,num){
        //定义辅助字符串
        var tmpstr=''
        for(let i=0;i<num;i++){
            tmpstr=s[i]+tmpstr
        }
        return str.substring(n)+tmpstr
        
    }