剑指 Offer 03. 数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/sh… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题意理解 找到数组中的任一重复数字 遍历当前数组, 如果索引 = 下标,则向后遍历,否则进行交换
// 比较好的一种方法
let cur
for (let i = 0; i < nums.length; i++) {
while (nums[i] != i) {
cur = nums[i]
if (nums[i] == nums[cur]) {
return nums[i];
} else {
nums[i] = nums[cur];
nums[cur] = cur;
}
}
}
// 牺牲速度 减少内存消耗
// for (let i = 0; i < nums.length; i++) {
// console.log(nums[i],nums.indexOf(nums[i]),nums.lastIndexOf(nums[i]));
// if (nums.indexOf(nums[i]) == nums.lastIndexOf(nums[i])) {
// console.log(1);
// continue;
// }
// return nums[i]
// }
// 使用Set
// let newNums = new Set();
// for (let i = 0; i < nums.length; i++) {
// if (newNums.has(nums[i])) {
// return nums[i]
// }
// newNums.add(nums[i])
// }
// 利用值即索引
// let newNums = [];
// for (let i = 0; i < nums.length; i++) {
// if (newNums[nums[i]] === nums[i]) {
// return nums[i]
// }
// newNums[nums[i]] = nums[i]
// }
// 暴力
// let newNums = [];
// for (let i = 0; i < nums.length; i++) {
// if(!newNums.includes(nums[i])){
// newNums.push(nums[i])
// continue
// }
// return nums[i]
// }
// 使用Map
// let map = new Map();
// for (let i = 0; i < nums.length; i++) {
// if (map.has(nums[i])) {
// return nums[i]
// }
// map.set(nums[i], 1)
// }
剑指 Offer 53 - I. 在排序数组中查找数字 I
统计一个数字在排序数组中出现的次数。
题意分析 数组已排序, 所以只需查找改数字的起始位置就可以统计出来
目前我已知好的方法
var search = function(nums, target) {
const startIndex = nums.indexOf(target)
const endIndex = nums.lastIndexOf(target)
if (startIndex === -1) {
return 0
}
return endIndex - startIndex + 1
};
剑指 Offer 53 - II. 0~n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
题意分析 题中给出的数组索引和索引值相同, 不相同的就是索要找的数字
- 先把边界值处理一下;如果nums[0]!==[0]或nums.length===0,则返回0;如果nums[nums.length-1]===nums.length-1,则返回nums.length
- 其他情况在中间,二分查找即可,终止条件left>right,返回left; 如果mid===nums[mid],在要找的数在右边;否则在左边
function missingNumber(nums) {
// for (let i = 0; i < nums.length; i++) {
// if (nums[i] !== i) {
// return i
// }
// }
// return nums.length
// 二分查找
const length = nums.length;
if (!length) {
return 0
}
let left = nums[0];
let right = nums[length - 1];
if (right === length - 1) {
return length
}
if (left !== 0) {
return 0
}
while (left <= right) {
let mid = (left + right) / 2 | 0;
if (mid === nums[mid]) {
left = mid + 1
} else {
right = mid - 1
}
}
return left
// 递归加二分
// const length = nums.length;
// if (!length) {
// return 0
// }
// let left = nums[0];
// let right = length - 1;
// // 处理边界
// if (nums[right] === right) {
// return length
// }
// if (left !== 0) {
// return 0
// }
// function rec(num1, num2) {
// let mid = (num1 + num2) / 2 | 0;
// if (num1 > num2) {
// return num1;
// }
// if (nums[mid] === mid) {
// return rec(mid + 1, num2)
// }
// if (nums[mid] > mid) {
// return rec(num1, mid - 1)
// }
// }
// const res = rec(left, right)
// return res;
}