11. 盛最多水的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。 示例 1:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入: height = [1,1]
输出: 1
解题思路:这题的要去其实就是求最大面积,给的数据是高度,宽度是每个高度对应的索引,这题可以用双指针来做,从数组的开头和结尾向中间进行,获取最大面积,那边高度小就向前进一步,代码如下:
var maxArea = function(height) {
// 设置指针i 和 j 分别从两个端点向中间前进
let i = 0, j = height.length - 1;
//默认最大面积是0
let maxS = 0;
while( i < j ){
//获取最小的高度
let min = Math.min(height[i],height[j]);
//最小高度乘以两个柱子的宽就是面积
let s = min * (j - i);
//更新最大面积
maxS = s > maxS ? s : maxS;
//谁小谁向前进
if(height[i] > height[j]) j --;
else i ++;
}
return maxS;
};
470. 用 Rand7() 实现 Rand10()
给定方法 rand7 可生成 [1,7] 范围内的均匀随机整数,试写一个方法 rand10 生成 [1,10] 范围内的均匀随机整数。
你只能调用 rand7() 且不能调用其他方法。请不要使用系统的 Math.random() 方法。
每个测试用例将有一个内部参数 n,即你实现的函数 rand10() 在测试时将被调用的次数。请注意,这不是传递给 rand10() 的参数。
示例 1:
输入: 1
输出: [2]
示例 2:
输入: 2
输出: [2,8]
示例 3:
输入: 3
输出: [3,8,10]
解题思路:rand2() 就是等概率生成1和2,就是在数组[1,2]随机获取,1和2的概率一样,rand3()在数组[1,2,3],1 2 3的概率一样,[1,2,3] 和 [1,1,2,2,3,3]是一样的因为概率相同,这题要做的就是生成一个数组里面获取一到十的概率一样,比如我们由rand10()变化成rand7(),就是在rand7() 的时候继续随机获取,直到获取到7以下,由推论我们可以得到两个公式小变大(RX - 1)* Y + RY = RXY,大变小就是 RX % R + 1 = RR,大于R的话就重新选择,代码如下:
var rand10 = function() {
//保持循环遍历,直到找到满足条件的数字,
while(true){
//因为我们只能用rand7(),因为我们只能用rand7(),所以这里我们Y都取7,此时num等于 rand49();
let num = (rand7() - 1) * 7 + rand7();
//四十以下的对10取余概率是一样的,所以只要小于等于40都是满足rand10();此时大于40的数字都是浪费的,可以知道浪费了9个值
if(num <= 40) return num % 10 + 1;
//此时num大于40为了减少浪费可以再转换成rand63(),这样浪费的数字四三个,
num = (num - 40 - 1) * 7 + rand7();
if(num <= 60) return num % 10 + 1;
//此时大于60我们可以转换成rand21(),只浪费1个,
num = (num - 60 - 1) * 7 + rand7();
if(num <= 20) return num % 10 + 1;
}
return num
};
239. 滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入: nums = [1], k = 1
输出: [1]
解题思路:这题的解题思路是,用一个数组来保存滑窗的宽度,然后找出改滑窗最大值,保存起来,然后往后遍历,当遍历范围超出k了就删除滑窗第一个数,代码如下
var maxSlidingWindow = function(nums, k) {
if(k <= 1) return nums;
//滑窗的宽度,最大是k
let q = [];
//存储最大值
let ans = [];
//从数组0开始遍历
let i = 0;
while(i < nums.length){
//当数组存在且刚超出k的时候删除第一个数,保持q存的是i到 i + k之间的值
if(q.length && q[0] + k <= i) q.shift();
//遍历查询滑窗内最大值
while(q.length && nums[q[q.length - 1]] <= nums[i]) q.pop();
//将当前所有储存在滑窗里
q.push(i);
//继续遍历下去
i ++;
//当i等于k时第一个最大值出现就是滑窗的第一个值,此后每次都会出现一个最大值
if(i >= k) ans.push(nums[q[0]]);
}
return ans;
};