自己总结下刷完剑指offer,使用js的实现等。
一、二维数组的查找
题目描述: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
方法一: 把每一行看成有序递增的数组,利用二分查找,通过遍历每一行去得到是否含有该整数, 时间复杂度: O(n*logn)
function Find(target, array)
{
// write code here
for(let i = 0; i < array.length;i++){
if(binarySearch(target,array[i])){
return true;
}
}
return false;
}
function binarySearch(target,arr){
let low = 0;
let high = arr.length - 1;
while(low <= high){
let mid = parseInt((low + high) / 2);
if(target < arr[mid]){
high = mid - 1;
}else if(target > arr[mid]){
low = mid + 1;
}else if(target == arr[mid]) {
return true;
}else return false;
}
return false;
}
方法二: 矩阵是有序的,从左下角来看,向上数字递减,向右数字递增。 因此从左下角开始查找,当要查找的数字比左下角数字的时候,向右移动; 当要查找的数字比左下角数字小时,向上移动。 时间复杂度: O(行高 + 列宽) , 空间复杂度: O(1)
function Find(target, array)
{
// write code here
let row = array.length;
let col = array[0].length;
if (row == 0 || col == 0) return false;
let i = row - 1;
let j = 0;
while(i >= 0 && j < col){
if (target < array[i][j]) {
i--;
continue;
} else if (target > array[i][j]) {
j++;
continue;
} else {
return true;
}
}
return false;
}
方法三: 一行代码,实用型
function Find(target, array) {
return array.some(arr => arr.some(e => e === target))
}
二、 重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
方法一: 利用hash,也就是js里面的{};
function duplicate(numbers, duplication)
{
// write code here
//这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
//函数返回True/False
var len = numbers.length;
var obj = {};
for(var i = 0; i < len; i++) {
if(numbers[i] in obj) {
duplication[0] = numbers[i];
return true;
} else {
obj[numbers[i]] = 1;
}
}
return false;
}
方法二:
- 把当前序列当成是一个下标和下标对应值是相同的数组;
- 遍历数组,判断当前位的值和下标是否相等: 2.1. 若相等,则遍历下一位; 2.2. 若不等,则将当前位置i上的元素和a[i]位置上的元素比较:若它们相等,则成功; 若不等,则将它们两交换。换完之后a[i]位置上的值和它的下标是对应的,但i位置上的元素和下标并不一定对应;
- 重复2.2的操作,直到当前位置i的值也为i,将i向后移一位,再重复2.
时间复杂度O(n), 空间复杂度O(1)
function duplicate(numbers, duplication)
{
// write code here
//这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
//函数返回True/False
let len = numbers.length;
if (numbers == null || len <= 0) return false;
for(let i = 0; i < len; i++) {
while(numbers[i] != i) {
if (numbers[i] == numbers[numbers[i]]) {
duplication[0] = numbers[i];
return true;
}
let temp = numbers[i];
numbers[i] = numbers[temp];
numbers[temp] = temp;
}
}
return false;
}
三、构建乘积数组
给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]A[1]...*A[i-1]A[i+1]...*A[n-1]。不能使用除法。(注意:规定B[0]和B[n-1] = 1)
B[i]的值可以看作下图的矩阵中每行的乘积。 先算下三角中的连乘,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
function multiply(a)
{
// write code here
var len = a.length;
var b = [];
if (len != 0) {
b[0] = 1;
<!-- 计算下三角连乘 -->
for(var i = 1; i < len; i++) {
b[i] = b[i-1] * a[i-1];
}
var temp = 1;
<!-- 计算上三角 -->
for(var j = len - 2; j >= 0; j--) {
temp *= a[j+1];
b[j] *= temp;
}
}
return b;
}