leetcode刷题之数组

字符串常见方法

  1. str.length获取字符串长度
  2. str[0]获取指定索引位置的元素
  3. str.indexOf(‘xiao’)查找指定字符串并返回下标(>=0)。如果找不到指定字符串,返回-1
  4. str.slice(2,6)截取字符串,第二个下标所在元素不包括。当第二个参数省略时,一直截取到最后一个,不影响原来的字符串
  5. toLowerCase() toUpperCase()
  6. str.replace(被换下,被换上的)第一个参数使用正则表达式/app/g时可以全局把app替换成别的,不影响原来的字符串
  7. str.split(‘,’)字符串转为数组,用逗号分割

数组常见方法

数组中可以存储任意类型的值[0,‘apple’,[1,‘888’,‘niu’],99,108]

  1. arr.length获取数组长度
  2. arr[0]获取指定索引位置的元素
  3. arr[0]=xxx修改某个元素
  4. arr=str.split(‘@’)字符串转为数组
  5. str=arr.join(‘@’)数组的每个元素用@连接起来形成字符串
  6. str=arr.toString()数组转为字符串,不能设置分割符
  7. myArray.push(‘Bradford’, ‘Brighton’)数组末尾追加元素,修改原来数组,返回添加后的数组长度
  8. myArray.pop()数组末尾删除元素,修改原来数组,返回删除的元素
  9. myArray.unshift(‘app’,‘fish’)数组开头添加元素,修改原来数组,返回添加后的数组长度
  10. myArray.shift()从数组开头删除元素,修改原来数组,返回删除的元素

leetcode数组基本题型

在这里插入图片描述

二分法

1、查找数组元素

  1. 前提:数组是有序的,无重复元素的
  2. 代码演示
var search = function(nums, target) {
    let left = 0;
    let right = nums.length - 1;
    while (left <= right) {
        let mid = left + Math.floor((right-left) / 2);
        if (nums[mid] > target) {
            right = mid - 1;
        }else if (nums[mid] < target) {
            left = mid + 1;
        }else {
            return mid;
        }
    }
    return -1;
};

2、查找插入元素位置

本质就是:先查找target是否等于数组中的元素,如果有相等的,则直接返回相等元素的下标即可;当不存在相等元素时,返回的是right+1,表示此元素插入在开头 或中间 或末尾。时间复杂度为O(logn)

var searchInsert = function(nums, target) {
    let left = 0;
    let right = nums.length - 1;
    while (left <= right) {
        let mid = left + Math.floor((right - left) / 2);
        if (nums[mid] > target) {
            right = mid - 1;
        }else if (nums[mid] < target) {
            left = mid + 1;
        }else {
            return mid;
        }
    }
    return right + 1;
};

3、查找最先出现和最后出现的位置

留坑 leetcode中级

双指针

1、删除数组中指定元素

把不是target的元素取出来重头覆盖掉之前数组中的元素

// 时间复杂度为O(n),把不是target的元素取出来重头覆盖掉之前数组中的元素
var removeElement = function(nums, val) {
    let k = 0;
    for (let i = 0; i < nums.length; i++) {
    	if (nums[i]! == val) {
    		nums[k++] = nums[i];
    	}
    }
    return k;
};

// 使用数组的splice方法
var removeElement = function(nums, val) {
    let i = 0;
    while (i < nums.length) {
    	if (nums[i] === val) {
    		nums.splice(i,1);
    	}else{
    		i++;
    	}
    }
    return nums.length;
};

2、使数组前k项是不重复的

1、本质上就是遍历数组,把数组中每个元素第一次出现的元素,取出来重新放到数组的0 1 2 位置
2、什么是第一次出现,即indexOf (nums[i]) === i

var removeDuplicates = function(nums) {
	let i = 0, k = 0;
	while (i < nums.length) {
		if (nums.indexOf(nums[i] === i)) {
			nums[k++] = nums[i];
		}
		i++;
	}
	return k;
}

3、把零元素移动到数组末尾

1、先把非零的移到前面
2、循环结束时,k在非零的下一位,那从这个位开始置零

var moveZeroes = function(nums) {
    // 先把非零的元素移到数组前面
    let k = 0;
    let i = 0;
    while (i < nums.length) {
        if (nums[i] !== 0) {
            nums[k++] = nums[i];
        }
        i++;
    }
    // 再把数组后面的元素置零
    for (let j = k; j < nums.length; j++) {
        nums[j] = 0;
    }
    return nums;
}; 

4、求有序数组的平方,并按从小到大顺序排列

1、暴力解法:把数组的平方push到一个新数组中,再对新数组sort排列,最后返回新数组即可

var sortedSquares = function(nums) {
    let result = [];
    for (let i = 0; i < nums.length; i++) {
        result.push(nums[i]*nums[i]);
    }
    result.sort((a,b)=>{
        return a-b;
    })
    return result;
};

2、由于本身是有序数组,则平方后的数组,最大值一定在两侧出现,因此可以使用双指针法,设置三个变量,一个表示左边的平方,第二个是右边元素的平方,第三个是插入的索引位置

var sortedSquares = function(nums) {
	let len = nums.length, i = 0, j = len - 1, k = len - 1;
	let result = new Array(len).fill(0);
	while (i <= j) {
		let left = nums[i] * nums[i],
			right = nums[j] * nums[j];
		if (left < right) {
			result [k--] = right;
			j--;
		}else{
			result [k--] = left;
			i++;
		}
	}
	return result ;
}

滑动窗口

1、寻找符合要求的最小子数组

使用滑动窗口求解:先遍历j往右扩张找到可行解,当找到时,再i往右+缩小窗口找到最优解

var minSubArrayLen = function(target, nums) {
	let i = 0, j = 0, sum = 0, len = nums.length, result = len + 1;
	while (j < len) {
		sum+= nums[j];
		while (sum >= target) {
			result = Math.min(result, j - i + 1);
			sum-= nums[i];  // i++缩小窗口得到最优解
			i++;
		} 
		j++;
	}
	return result === len + 1 ? 0 : result;  // result没变时说明没找到窗口,返回0
}

螺旋矩阵

本质就是遵循左闭右开的区间,依次把数字放入指定位置

var generateMatrix = function(n) {
	let startX = 0, startY = 0;
	let loop = Math.floor(n / 2);
	let mid = Math.floor(n / 2);
	let result= new Array(n).fill(0).map(()=>new Array(n).fill(0));
	let offset = 1, count = 1;
	while (loop--) {
		let row = startX; col = startY; 
		for (;col < startY + n - offset; col++) {
			result[row][col] = count++;
		}
		for(;row < startX + n - offset; row++) {
			result[row][col] = count++;
		}
		// startX
		for(;col > startX; col--) {
			result[row][col] = count++;
		}
		for(;row > startY; row--) {
			result[row][col] = count++;
		}
		startX++;
		startY++;
		offset+=2;
	}
	if (n % 2){
		result[mid][mid] = count;
	}
	return result;
	
}

看完这篇记得手撕代码小魏,要不然还是会忘

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值