Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
一、前言
刷题啊!!!
开始刷 “剑指 Offer” 31天。刷完时间:2022.3.6 ~ 2022.3.20。
二、题目
题目:
- 数组中出现次数超过一半的数字
- 构建乘积数组
(1)剑指 Offer 39. 数组中出现次数超过一半的数字
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:1 <= 数组长度 <= 50000
题解
这种方法蛮多的:
- 辅助
HashMap来记录出现次数 - 排序
- 摩尔投票法:核心理念为:票数正负抵消
那么主要讨论摩尔投票法。
思路:若为众数,则 + 1; 若不为众数,则 -1;
因为众数,票数最后一定 > 0。
步骤如下:
- 若票数
votes为 0, 则更新众数x - 若当前数等于 众数
x,则 +1; 反之 -1 - 最后找到了
x,但还要判断下这个x是否占大多数
AC 代码如下:
class Solution {
// Time: O(n), Space: O(1), Faster: 99.97%
public int majorityElement(int[] nums) {
int x = 0, votes = 0;
// 1. 找到 x
for (int num : nums) {
if (votes == 0) x = num;
votes += num == x ? +1 : -1;
}
// 2. 判断是否众数
int cnt = 0;
for (int num : nums) {
if (num == x) ++cnt;
}
return cnt > nums.length / 2 ? x : -1;
}
}
(2)剑指 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]。不能使用除法。
示例:
输入: [1,2,3,4,5]
输出: [120,60,40,30,24]
提示:
- 所有元素乘积之和不会溢出 32 位整数
a.length <= 100000
题解
思路:
- 初始化数组
B,B[0] = 1, 辅助变量tmp = 1 - 计算
B[i]的下三角各元素的乘积 - 计算
B[i]的上三角各元素的乘积,记为tmp,同时乘入B[i]
AC 代码如下:
class Solution {
public int[] constructArr(int[] a) {
int len = a.length;
if(len == 0) return new int[0];
int[] b = new int[len];
b[0] = 1;
int tmp = 1;
for(int i = 1; i < len; i++) {
b[i] = b[i - 1] * a[i - 1];
}
for(int i = len - 2; i >= 0; i--) {
tmp *= a[i + 1];
b[i] *= tmp;
}
return b;
}
}