剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
题意理解 找出数组中出现超过一半的数,次数一定存在
- 声明两个变量,一个用来存储当前数,一个用来计算当前抵消出现次数最多的数
- 遍历结束,返回当前抵消后的数
摩尔投票法: 查找输入数据中重复的数据超过一般,必须超过一半,等于不算,一定存在这个数
var majorityElement = function(nums) {
let count = 0;
let currentNum = 0;
nums.forEach(num => {
if (count < 1) {
currentNum = num;
}
num === currentNum ? count++ : count--
})
return currentNum
};
哈希表统计法
var majorityElement = function(nums) {
let map = new Map()
for (let i = 0; i < nums.length; i++) {
if (map.has(nums[i])) {
map.set(nums[i], map.get(nums[i]) + 1)
} else {
map.set(nums[i], 1)
}
}
let value;
map.forEach((val, key) => {
if (val >= (nums.length) / 2) {
value = key;
}
})
return value;
}
剑指 Offer 66. 构建乘积数组
给定一个数组 A[0, 1, …, n-1],请构建一个数组 B[0, 1, …, n-1],其中B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
题意理解: B数组中的数据等于A中所有数据的乘积然后除以自生,因为不能使用除法,所以此方法弃用 再计算B[i]的时候,可以将A[i]看成1与其他A中数据的乘积 可以列出一个表格,看成1的数据就是一条斜线,将表格分成左下和右上两个部分,这样就可以找出规律
- 左下区域,可以使用递推一次计算,及B1[i] = A[0] * A[1] ... A[i-1]
- 右上区域,可以使用倒叙递推一次计算,及B2[0] = A[i-1] * A[i-2] ... A[0]
- 最终结果B[i] = B1[i] * B2[i]
B\A | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | 1 | 2 | 3 | 4 | 5 |
2 | 1 | 1 | 3 | 4 | 5 |
3 | 1 | 2 | 1 | 4 | 5 |
4 | 1 | 2 | 3 | 1 | 5 |
5 | 1 | 2 | 3 | 4 | 1 |
表格分区
var constructArr = function (a) {
if (!a.length) return [];
let arr = [1]
for (let i = 1; i < a.length; i++) {
arr[i] = arr[i - 1] * a[i - 1]
}
console.log(arr);
let temp = 1;
for (let i = a.length - 1; i >= 0; i--) {
arr[i] = arr[i] * temp;
temp *= a[i]
}
return arr;
};