常见的几道算法题

  最近在笔试和看面经的时候经常会碰到几道算法题目,决定记录下来和大家分享以下。

求数组的最大字段和

  比如:arr=[1,-2,3,10,-4,7,2,-5],求它的最大的和是多少,答案是18 。问题来了:那为什么最后结果是18呢?思考… …?

  一波分析:首先,sum = 1+(-2)< 0,这种情况下sum = 0 ,并且从3开始加。

  总结:遇到正数直接加上,遇到负数先判断加上当前的元素后和是不是小于0,是的话就重新计算,否则直接加上。

// 最大字段和
    function maxNumber(arr) {
        var max=0;   //保存最大值
        var sum=0;  //保存当前值
        for(let i=0;i<arr.length;i++){
            if(arr[i]>=0){   //正数的情况
                sum+=arr[i];
                max=sum>max?sum:max;   //判断,改变max值
            }else{                  //负数情况
                if(sum+arr[i]>0){
                    sum+=arr[i];
                }else{
                    sum=0;
                }
            }
        }
        return max;
    }
两个字符串的最长公共子串

  最长公共子串是指两个字符串中相同的字符串,同时还是最长的。比如:“abcdef” 和 “defg” 公共且最长是 “def”。

  过程:先找到长度最短的字符串,把短字符串的子序列枚举出来,依次到长字符串中进行判断是否存在,每次从最长的开始判断,存在就直接返回。

function MaxCommon(str1,str2) {
	if(str1.length > str2.length){
		var temp = str1;
		str1 = str2;
		str2 = temp;
	}
	let len1 = str1.length;
	let len2 = str2.length;
	for(let i=len1; i>0; i--){
		for(let j=0; j<=len1-i; j++){
			let str = str1.substr(j,i);
			if(str2.indexOf(str)>=0){
				return str;
			}
		}
	}
	return "";
}
最长递增子序列

  最长递增子序列意思是在一组数字中,找出最长一串递增的数字,比如:0, 3, 4, 17, 2, 8, 6, 10 对于以上这串数字来说,最长递增子序列就是 0, 3, 4, 8, 10

function Lengthest(nums){
	let array = Array(nums.length).fill(1);  //以1填充数组
	for(let i = 1;i<array.length;i++){
		for(let j = 0;j<i;j++){  //和之前的所有元素进行比较
			if(nums[i]>nums[j]){
				array[i] = Math.max(array[i],1+array[j]);   //取最大值
			}
		}
	}
	return Math.max(...array);  //返回长度
}
var arr = [0, 3, 4, 17, 2, 8, 6, 10];
console.log(Lengthest(arr));   //5
柯里化

  经典考题:add(1)(2)(3)(),add(1,2,3)都返回6。

  柯里化是将一个n元函数转为n个一元函数

  函数柯里化好处:1、提高参数复用性 2、延迟执行(累计传入参数,最后执行)

//先来个 add(1,2)和add(1)(2)
function add(){
	var sum=0;
	if(arguments.length ===1){
		sum = arguments[0];
		return function(y){
			return sum+=y;
		}
	}else{
		return sum=arguments[0]+arguments[1];
	}
}

  上面的只能实现两个参数的情况,当参数再增加的情况就不适用了。add(1)(2)(3)会报错 Uncaught TypeError: add(…)(…) is not a function 。所以应该封装一个都通用的函数。

function sum(...args){//这里的三个点...是扩展运算符,该运算符将一个数组,变为参数序列。
	if([...args].length==1){//判断参数个数的形式是否为1个,即第二种形式
		var cache = [...args][0];//将第一个参数的值暂存在cache中
		var add = function (y){//创建一个方法用于实现第二个条件,最后并返回这个方法
            cache += y;
			return add; 
        }
        add.toString = function () { return cache }
	    return add; 
	}else{
		var res = 0;//这里最好先声明要输出的变量,并给其赋值,不然值定义而不赋值会输出NaN,因为js将undefined+number两个数据类型相加结果为NaN
		for(var i = 0;i<[...args].length;i++){
			res += [...args][i]; //参数累加
        }
        return res;
	} 
} 
console.log(sum(2,3,4));
console.log(sum(2)(3)(4)(5));
原生js实现splice()函数

  这一题是我今天看牛客面经的时候看到的一道题,挺不错的,实习的话就需要对splice函数中的每一项参数都特别理解,之前可能对每一项参数都特别模糊,趁着现在好好复习一下。

  splice(参数一,参数二,参数三),要了解的是该函数会改变原数组。。。

  参数一:如果只有该参数,则删除从该值后的所有元素,splice返回的是被删除的元素

  参数二:如果为0,不操作数组,返回空数组,否则表示删除数组的长度

  参数三:表示要插入的值。

  // 实现splice()
    Array.prototype.mySplice = function () {
        var arr = this;
        var res = [], temp = [];
        if (arguments.length == 1) {   //存在第一个参数情况
            for (let i = arguments[0]; i < arr.length; i++) {
                res.push(arr[i]);
            }
            for (let i = 0; i < arguments[0]; i++) {
                temp.push(arr[i]);
            }
            arr = temp;  //改变原数组
            return res;   
        } else { 
            if (arguments[1] == 0 || arguments[1] > arr.length) {  
                return [];   //第二个参数为0,或者超过原数组的情况
            } else {
                let k = arguments[1];  //保存下来,后面取值会用到
                let n = arguments[0]
                for (let i = n; i < arr.length; i++) {
                    res.push(arr[i]);
                    arguments[1]--;  //第二个参数减减
                    if (arguments[1] <= 0) {
                        var array = Object.assign([], arr);  //浅拷贝
        //会有删除中间元素的情况,这样的话就要取到第一个被删除元素前的,和最后被删除后的元素
        //比如[1, 2, 4, 5, 8, 7] 删除[2,4,5] ,那么原数组为[1,8,7]
                        for (let i = 0; i < n; i++) {  //取到[1]
                            temp.push(array[i])
                        }
                        for (let i = k; i < array.length; i++) {  //取到[8,7]
                            temp.push(array[i])
                        }
                        arr = temp;  //赋值给原数组
                        break;
                    }
                }
                if (arguments[2]) {  //存在第三个函数的情况,做插入
                    arr[n] = arguments[2];
                }
            }
            return res;
        }
    }
    var arr = [1, 2, 4, 5, 8, 7];
    console.log(arr.mySplice(1,3,44));

  实现splice是我自己实现的,程序可能存在不完美的之处,欢迎指出。

  期待大家共同进步?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值