https://leetcode-cn.com/problems/boats-to-save-people/submissions/
这道题重点在于,一艘船上最多坐两个人,这样题目就简单了
第一种方法很好理解,大家按身高排队,重量大的先上船,如果此时能有个质量轻的一起上就一起走
第二种的基本思想和第一种一样,但是题目里limit的上限不高,而且都是整数,所以可以用上计数排序的思想(我做题时怎么没想到)
//排序,重的先上,如果能再加个人,就一起走
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int ans = 0;
for (int i = 0, j = people.length - 1; i <= j; ) {
if (people[i] + people[j] <= limit) {
i++;
j--;
} else {
//没人能和你凑合,你先走吧
j--;
}
ans++;
}
return ans;
}
法2
//有点类似计数排序
public int numRescueBoats(int[] people, int limit) {
int ans = 0;
//重量的数组
int[] heights = new int[limit + 1];
for (int i = 0; i < people.length; i++) {
heights[people[i]]++;
}
int i = 0;
int j = limit;
while (heights[j] == 0) {
j--;
}
while (heights[i] == 0) {
i++;
}
while (i < j) {
if (i + j > limit) {
ans += heights[j];
j--;
while (heights[j] == 0&&j>=0) {
j--;
}
} else {
int t = Math.min(heights[i], heights[j]);
ans += t;
heights[i] -= t;
heights[j] -= t;
while (j>=0&&heights[j] == 0) {
j--;
}
while (i<=limit&&heights[i] == 0) {
i++;
}
}
}
//这个很特别,如果剩余的质量不足limit一半,可以两人一船,否则一人一船
if(i==j){
ans += (2*i>limit)?heights[i]:(heights[i]+1)/2;
}
return ans;
}