我们对 0 到 255 之间的整数进行采样,并将结果存储在数组 count 中:count[k] 就是整数 k 的采样个数。
我们以 浮点数 数组的形式,分别返回样本的最小值、最大值、平均值、中位数和众数。其中,众数是保证唯一的。
我们先来回顾一下中位数的知识:
示例 1:
输入:count = [0,1,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出:[1.00000,3.00000,2.37500,2.50000,3.00000]
示例 2:
输入:count = [0,4,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出:[1.00000,4.00000,2.18182,2.00000,1.00000]
提示:
count.length == 256
1 <= sum(count) <= 10^9
计数表示的众数是唯一的
答案与真实值误差在 10^-5 以内就会被视为正确答案
//最小值、最大值、平均值、中位数和众数
public static double[] sampleStats(int[] count) {
//某数出现的最大次数
int maxModeCount = Integer.MIN_VALUE;
//数总和
double sum = 0.0;
//记录数的总个数
int countNum = 0;
//结果数组
double[] res = new double[5];
//中位数的下标
int midIndex = count[0];
boolean flag = true;
for (int i = 0; i < count.length; i++) {
//求最小值,从左至右第一次出现的数,即第一次array[i]!=0时候
//求最大值,从左至右最后一次出现的数,即最后一次array[i]!=0时候(每次更新即可)
if (count[i] != 0) {
if (flag) {
flag = false;
res[0] = (double) i;
}
res[1] = (double) i;
}
//求众数,即求max(array[i]),那么i就是众数
if (count[i] > maxModeCount) {
maxModeCount = count[i];
res[4] = (double) i;
}
//记录所有数出现的次数
countNum += count[i];
//求和
sum += count[i] * i;
//中位数在的位置
midIndex = countNum / 2;
}
res[2] = sum / countNum;
//元素数量为偶数时,中位数为中间的两个元素的平均值,所以需要找到已知中位数的下一个数
double midNum = 0;
double midNumNext = 0;
//再次遍历求中位数
int cnt = 0;
for (int i = 0; i < count.length; i++) {
cnt += count[i];
//找到了
if (cnt >= midIndex) {
//如果刚好等于,那么就继续遍历找到下一个数即可
if (cnt == midIndex) {
midNum = i;
for (int j = i + 1; j < count.length; j++) {
if (count[j] != 0) {
midNumNext = j;
break;
}
}
break;
} else {
//cnt>midIndex
midNum = i;
midNumNext = i;
break;
}
}
}
//偶数
if (countNum % 2 == 0) {
res[3] = (midNum + midNumNext) / 2;
} else {
res[3] = midNum;
}
return res;
}
假设你是一位顺风车司机,车上最初有 capacity 个空座位可以用来载客。由于道路的限制,车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向,你可以将其想象为一个向量)。
这儿有一份行程计划表 trips[][],其中 trips[i] = [num_passengers, start_location, end_location] 包含了你的第 i 次行程信息:
这些给出的地点位置是从你的 初始 出发位置向前行驶到这些地点所需的距离(它们一定在你的行驶方向上)。
请你根据给出的行程计划表和车子的座位数,来判断你的车是否可以顺利完成接送所用乘客的任务(当且仅当你可以在所有给定的行程中接送所有乘客时,返回 true,否则请返回 false)。
示例 1:
输入:trips = [[2,1,5],[3,3,7]], capacity = 4
输出:false
示例 2:
输入:trips = [[2,1,5],[3,3,7]], capacity = 5
输出:true
示例 3:
输入:trips = [[2,1,5],[3,5,7]], capacity = 3
输出:true
示例 4:
输入:trips = [[3,2,7],[3,7,9],[8,3,9]], capacity = 11
输出:true
public static boolean carPooling(int[][] trips, int capacity) {
if(trips.length<=0){
return true;//false?
}
if(trips.length==1&&trips[0][0]<=capacity){
return true;
}else if(trips.length==1){
//trips[0][0]>capacity
return false;
}
//trips.length>1
//排序,以所有行程的上车地点来升序排序
Arrays.sort(trips, new Comparator<int[]>() {
public int compare(int[] arr1, int[] arr2) {
return arr1[1] - arr2[1]; //按照区间第二个数大小!!!!!!
}
});
for(int[] t:trips){
for(int a:t){
System.out.print(" "+a);
}
System.out.println();
}
//双向队列来辅助操作,队列里面维护一个,从左到右依次先下车的序列,
LinkedList <int[]> list=new LinkedList<>();
//第一个入队
list.add(trips[0]);
int nowCapacity=trips[0][0];
for(int i=1;i<trips.length;i++){
//遍历list,如果list左边乘客的下车点已经<=现在乘客的上车点,那么下车(出队)
while(list.size()>0&&list.getFirst()[2]<=trips[i][1]){
//左边出队
int []tmp=list.pollFirst();
//更新容量
nowCapacity-=tmp[0];
}
list.add(trips[i]);
Collections.sort(list, new Comparator<int[]>() {
public int compare(int[] arr1, int[] arr2) {
return arr1[2] - arr2[2]; //按照区间第3个数大小!!!!!!
}
});
nowCapacity+=trips[i][0]; //13
//查看当前是否超载
if(nowCapacity>capacity){
System.out.println(nowCapacity);
return false;
}
}
return true;
}
另一种解法:
public boolean carPooling02(int[][] trips, int capacity) {
TreeMap<Integer,Integer> tmap = new TreeMap<>();
for(int i=0;i<trips.length;++i){
Integer startNum = tmap.get(trips[i][1]);
Integer endNum = tmap.get(trips[i][2]);
if(startNum == null)
startNum =0;
if(endNum == null)
endNum=0;
startNum=startNum+trips[i][0];
endNum=endNum-trips[i][0];
tmap.put(trips[i][1],startNum);
tmap.put(trips[i][2],endNum);
}
int carry = 0;
for(Integer p:tmap.keySet()){
carry+=tmap.get(p);
if(carry>capacity)
return false;
}
return true;
}
(这是一个 交互式问题 )
给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。
如果不存在这样的下标 index,就请返回 -1。
所谓山脉数组,即数组 A 假如是一个山脉数组的话,需要满足如下条件:
首先,A.length >= 3
其次,在 0 < i < A.length - 1 条件下,存在 i 使得:
你将 不能直接访问该山脉数组,必须通过 MountainArray 接口来获取数据:
示例 1:
输入:array = [1,2,3,4,5,3,1], target = 3
输出:2
解释:3 在数组中出现了两次,下标分别为 2 和 5,我们返回最小的下标 2。
原题地址:https://leetcode-cn.com/contest/weekly-contest-142/problems/find-in-mountain-array/
引用答案:
public int findInMountainArray(int target, MountainArray mountainArr) {
int len=mountainArr.length(),idx=-1;
int left=0,right=len-1;
while(left<=right){
int mid=(left+right)/2;
if(mid==0){
left=mid+1;
continue;
}
if(mid==len-1){
right=mid-1;
continue;
}
int l=mountainArr.get(mid-1),r=mountainArr.get(mid+1),cur=mountainArr.get(mid);
if(l<cur&&r<cur){
idx=mid;
break;
}else if(l>cur&&cur>r) {
right = mid - 1;
}else{
left=mid+1;
}
}
left=0;
right=idx;
while(left<=right){
int mid=(left+right)/2;
int cur=mountainArr.get(mid);
if(cur==target){
return mid;
}else if(cur>target) {
right = mid - 1;
}else{
left=mid+1;
}
}
left=idx+1;
right=len-1;
while(left<=right){
int mid=(left+right)/2;
int cur=mountainArr.get(mid);
if(cur==target){
return mid;
}else if(cur<target) {
right = mid - 1;
}else{
left=mid+1;
}
}
return -1;
}
如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。
花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串,定义下面几条语法规则:
原题地址:https://leetcode-cn.com/contest/weekly-contest-142/problems/brace-expansion-ii/
引用答案:
class Node {
List<String> res = new ArrayList<>();
int idx;
}
Node solve(String str, int start) {
Set<String> res = new HashSet<>();
res.add("");
StringBuilder sb = new StringBuilder();
for (int i = start; i < str.length(); i++) {
if (str.charAt(i) == ' ') continue;
if (str.charAt(i) == '{') {
if (sb.length() > 0) {
Set<String> nres = new HashSet<>();
for (String s : res) {
nres.add(s + sb.toString());
}
res = nres;
sb = new StringBuilder();
}
Node ans = solve(str, i + 1);
Set<String> nres = new HashSet<>();
for (String s : res)
for (String s2 : ans.res) {
nres.add(s + s2);
}
res = nres;
i = ans.idx;
} else if (str.charAt(i) == ',') {
if (sb.length() > 0) {
Set<String> nres = new HashSet<>();
for (String s : res) {
nres.add(s + sb.toString());
}
res = nres;
sb = new StringBuilder();
}
Node ans = solve(str, i + 1);
res.addAll(ans.res);
ans.res.clear();
ans.res.addAll(res);
return ans;
} else if (str.charAt(i) == '}') {
if (sb.length() > 0) {
Set<String> nres = new HashSet<>();
for (String s : res) {
nres.add(s + sb.toString());
}
res = nres;
sb = new StringBuilder();
}
Node ans = new Node();
ans.res.addAll(res);
ans.idx = i;
return ans;
} else {
sb.append(str.charAt(i));
}
}
if (sb.length() > 0) {
Set<String> nres = new HashSet<>();
for (String s : res) {
nres.add(s + sb.toString());
}
res = nres;
sb = new StringBuilder();
}
Node ans = new Node();
ans.res.addAll(res);
ans.idx = str.length();
return ans;
}
public List<String> braceExpansionII(String expression) {
Node res = solve(expression, 0);
Collections.sort(res.res);
return res.res;
}