Open azl397985856 opened 2 years ago
/**
* @param {number[]} people
* @param {number} limit
* @return {number}
*/
var numRescueBoats = function(people, limit) {
//从小到大排序
people.sort(function(a,b){return a-b;});
var left=0;
var right=people.length-1;
var count=0;
while (left<=right){
//两人一条船的情况
if(people[left]+people[right]<=limit){
count++;
left++;
right--;
//一人一条船的情况
}else{
right--;
count++;
}
}
return count;
};
贪心 \ sort people,双指针从两端 light 搭配 heavy 安排船
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int light = 0;
int heavy = people.length - 1;
int res = 0;
while (light <= heavy) {
if (people[light] + people[heavy] <= limit) {
res++;
light++;
heavy--;
} else {
res++;
heavy--;
}
}
// if (light == heavy) {
// return res + 1;
// }
return res;
}
}
时间: O(nlogn) \ 空间: O(logn)
贪心 + 双指针。要尽可能在一个船里面放两个人同时尽可能达到船只的限重,从而减少船只数量。首先将people排序,然后左右指针初始指向0和people.length - 1,分别为最小体重和最大体重的人。如果两个人加起来没有超过限重,我们把他们放到一个船里,船数加1,左指针右移,右指针左移。如果两个人加起来超过了限重,我们只能将大体重的人放到船中,因为people已经排好序,其他人都不比小体重的这个人轻,肯定无法将大体重和其他人共同放到船中,这时船数加1,右指针左移。以此方法直到将所有人都放到船里为止。最后返回船的数量。
class Solution {
public int numRescueBoats(int[] people, int limit) {
int len = people.length;
// sort people by weight in non-descending order
Arrays.sort(people);
int res = 0;
int l = 0, r = len - 1;
while (l <= r) {
// if the larger weight person and the smaller weight person
// can fit in one boat, put both in boat and move to next ones
if (people[r] + people[l] <= limit) {
res++;
l++;
r--;
}
// if cannot fit two people, only put the larger weight people in boat
else {
res++;
r--;
}
}
return res;
}
}
复杂度分析
title: "Day 67 881. 救生艇" date: 2021-11-15T11:45:01+08:00 tags: ["Leetcode", "c++", "Greed", "quick sort"] categories: ["91-day-algorithm"] draft: true
第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。
返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
示例 1:
输入:people = [1,2], limit = 3
输出:1
解释:1 艘船载 (1, 2)
示例 2:
输入:people = [3,2,2,1], limit = 3
输出:3
解释:3 艘船分别载 (1, 2), (2) 和 (3)
示例 3:
输入:people = [3,5,3,4], limit = 5
输出:4
解释:4 艘船分别载 (3), (3), (4), (5)
提示:
1 <= people.length <= 50000
1 <= people[i] <= limit <= 30000
- 1、贪心法加双指针,双指针的思考方法跟快排一致。
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
int ans = 0;
sort(people.begin(), people.end());
int l= 0, r = people.size() - 1;
while(l <= r)
{
if (people[l] + people[r] > limit) r--;
else
{
l++;r--;
}
ans++;
}
return ans;
}
};
时间复杂度:O(logn)
空间复杂度:O(1)
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
left, right = 0, len(people) - 1
res = 0
while left <= right:
if people[left] + people[right] <= limit:
left += 1
right -= 1
res += 1
return res
Go Code:
func numRescueBoats(people []int, limit int) int {
sort.Ints(people)
left, right := 0, len(people)-1
res := 0
for left <= right {
if people[left]+people[right] <= limit {
left++
}
right--
res++
}
return res
}
复杂度分析
令 n 为数组长度。
public int numRescueBoats(int[] people, int limit) {
int numOfBoat = 0;
Arrays.sort(people);
int left = 0;
int right = people.length - 1;
while (left <= right) {
if (people[left] + people[right] <= limit) {
left++;
right--;
} else {
right--;
}
numOfBoat++;
}
return numOfBoat;
}
https://leetcode-cn.com/problems/boats-to-save-people/
Greedy
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
# time nlogn
# space 1
people.sort()
count = 0
i, j = 0, len(people) - 1
# 无论people奇数偶数
# 当i==j时 最后一个人一定会被分一艘船 然后退出循环
while(i <= j):
# 最轻的人和最重的人搭配
if people[i] + people[j] <= limit:
count += 1
i += 1
j -= 1
# 搭配不成功就只能放下最重的人
else:
count += 1
j -= 1
return count
class Solution(object):
def numRescueBoats(self, people, limit):
"""
:type people: List[int]
:type limit: int
:rtype: int
"""
people.sort()
res = 0
cur = 0
left, right = 0, len(people)-1
while left <= right:
if people[left] + people[right] <= limit:
left += 1
right -= 1
else:
right -= 1
res += 1
return res
Idea: double pointers, greedy, nlogn
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
l = 0
r = len(people)-1
ans = 0
while l<r:
total = people[l] + people[r]
if total <= limit:
l += 1
r -= 1
ans +=1
else:
ans += 1
r -=1
if r == l:
ans += 1
return ans
相向双指针,如果是left 和 right对应的和 <= limit 那么可以一条船可以载两个,否则先载right
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
left, right, min_num_boats = 0, len(people) - 1, 0
while left <= right:
if people[left] + people[right] <= limit:
left += 1
right -= 1
min_num_boats += 1
return min_num_boats
Time O(nlgn)
Space O(1)
# greedy: try to pair heaviest person with the lightest person
# time: O(NlogN)
# space: O(1)
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort(reverse = True)
res = 0
left = 0
right = len(people) - 1
while left <= right:
# last person
if left == right:
res += 1
break
# carry current heaviest with lightest
if people[left] + people[right] <= limit:
right -= 1
res += 1
left += 1
return res
/**
* @param {number[]} people
* @param {number} limit
* @return {number}
*/
const numRescueBoats = function(people, limit) {
people.sort((a, b) => a - b);
let count = 0;
let left = 0;
let right = people.length - 1;
while (left <= right) {
if (people[left] + people[right] <= limit) {
left += 1;
right -= 1;
} else {
right -= 1;
}
count += 1;
}
return count;
};
/**
* @param {number[]} people
* @param {number} limit
* @return {number}
*/
var numRescueBoats = function (people, limit) {
let ans = 0
people.sort((a, b) => a - b)
let light = 0,
heavy = people.length - 1
while (light <= heavy) {
if (people[light] + people[heavy] <= limit) {
++light
}
--heavy
++ans
}
return ans
}
sort + two pointers\ if min + max weight <= limit, put all two in and move pointers;\ else, put the max weight people in
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
# sort and two pointers
people.sort()
i = 0
j = len(people) - 1
count = 0
while i <= j:
if people[i] + people[j] <= limit:
count += 1
i += 1
j -= 1
else:
count += 1
j -= 1
return count
https://leetcode-cn.com/problems/boats-to-save-people/
思路:对people的载重进行排序,先最大和最小的是否满足limit 不满足看第二大和最小的,否则最后单独做
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
start = 0
end = len(people)-1
count = 0
while start <= end:
if people[start]+people[end] <= limit:
count += 1
start += 1
end -= 1
else:
count += 1
end -= 1
return count
复杂度分析:
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
ans = 0
people.sort()
light, heavy = 0, len(people) - 1
while light <= heavy:
if people[light] + people[heavy] > limit:
heavy -= 1
else:
light += 1
heavy -= 1
ans += 1
return ans
贪心 + 双指针,先让体重最大的上船,然后如果还有空间,让体重最轻的人上船。
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int l = 0;
int r = people.length - 1;
int ans = 0;
while (l <= r) {
if (limit - people[r--] >= people[l]) {
l++;
}
ans++;
}
return ans;
}
}
TC: O(NLogN) 排序 SC: O(LogN) 排序
思路:
复杂度分析:
代码(C++):
方法一、排序,双指针(滑动窗口)
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
// greedy + two pointers
sort(people.begin(), people.end());
// user two pointers from left and right to select the most heavy and most light persons, and compare if can put two persons into one boat (p[l] + p[r] <= limit)
int l = 0, r = people.size() - 1;
int res = 0;
while (l <= r) {
if (people[l] + people[r] <= limit) {
++l;
--r;
} else
--r;
res++;
}
return res;
}
};
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
result=start=0
end=len(people)-1
while start<=end:
if people[start]+people[end] <=limit:
start+=1
end-=1
else:
end-=1
result+=1
return result
Time: O(nlogn)
Space: O(1)
class Solution {
public int numRescueBoats(int[] people, int limit) {
//救生梯问题。最重的和最轻的一起走。如果可以的话。否则最重的自己走
Arrays.sort(people);//对体重进行排序。
int left = 0; //最轻的
int right = people.length - 1; //最重的
int ans = 0;
while(left <= right) {
if(people[left] + people[right] <= limit) {
//最轻的和最重的能一起走的时候就一起走
ans++;
left++;
right--;
}else {
//否则最重的自己先走
ans++;
right--;
}
}
return ans;
}
}
贪心+双指针
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
ans = 0
end = len(people)-1
start =0
while start<=end:
if start == end:
return ans+1
if people[start]+people[end]<=limit:
ans+=1
start+=1
end-=1
else:
ans+=1
end-=1
return ans
复杂度分析
对人的体重进行排序,拿出最重的和最轻的人,如果在limit之内就一起坐船,否则就最重的自己坐,排序+双指针
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int res = 0;
int l = 0;
int r = people.size() - 1;
while (l <= r) {
int light = people[l];
int heavy = people[r];
if ((light + heavy) <= limit) {
l++;
r--;
} else {
r--;
}
res++;
}
return res;
}
};
思路: super straightforward, just sort the array then use two pointers to scan it
class Solution {
public int numRescueBoats(int[] people, int limit) {
if (people.length == 1) {
return 1;
}
Arrays.sort(people);
int start = 0, end = people.length - 1, result = 0;
while (start <= end) {
if (limit - people[end] >= people[start]) {
start++;
end--;
} else {
end--;
}
result++;
}
return result;
}
}
Time Complexity: O(nlogn) Space Complexity: O(1)
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
ans=[]
m=len(people)
left=0
right=m-1
while left<=right:
if people[left]+people[right]>limit:
right-=1
ans.append(people[right+1])
else:
left+=1
right-=1
ans.append((people[left-1],people[right+1]))
return len(ans)
先排序,最大和最小的两个能一起走就一起走,不能就最大的单独走
public int numRescueBoats(int[] people, int limit) {
if(people.length<2){
return people.length;
}
int sun = 0;
Arrays.sort(people);
int min = 0;
for (int i = people.length-1; i >=0 ; i--) {
if( min<=i){
int max = people[i];
if(max+people[min]<=limit){
min++;
}
sun++;
}
}
return sun;
}
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
res = 0
left, right = 0, len(people) - 1
people.sort()
while left < right:
total_weight = people[left] + people[right]
if total_weight > limit:
right -= 1
else:
right -= 1
left += 1
res += 1
return res + 1 if left == right else res
class Solution {
public int numRescueBoats(int[] people, int limit) {
int ans = 0;
Arrays.sort(people);
int light = 0, heavy = people.length - 1;
while (light <= heavy) {
if (people[light] + people[heavy] <= limit) {
++light;
}
--heavy;
++ans;
}
return ans;
}
}
var numRescueBoats = function(people, limit) {
// sort people + two pointers
people.sort((a, b) => a - b);
let l = 0;
let r = people.length - 1;
let result = 0;
while (l <= r) {
result++;
if (people[l] + people[r] <= limit) {
l++;
}
r--;
}
return result;
};
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int res = 0;
int left = 0, right = people.size() - 1;
while (left <= right) {
//当前最重和最轻的重量和>limit,则当前最重单独一条船
if (people[left] + people[right] > limit) {
--right;
}
//同乘一条船
else {
++left;
--right;
}
++res;
}
return res;
}
Greedy.
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
count = 0
people.sort()
l, r = 0, len(people) - 1
while l < r:
if people[l] + people[r] <= limit:
l += 1
r -= 1
count += 1
if l == r:
count += 1
return count
Time: O(nlogn). Space: O(1).
排序+双指针
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int left= 0, right = people.length - 1;
int count = 0;
while (left <= right) {
if (people[left] + people[right] <= limit) left++;
right--;
count++;
}
return count;
}
}
class 救生艇_881 {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int l = 0, r = people.length - 1, boat = 0;
// 每次装一个最重的 能带一个最轻的就带一个 带不了就自己走
while(l <= r) {
if((people[r] + people[l]) <= limit) {
l ++;
}
r--; boat++;
}
return boat;
}
}
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
ans = 0
people.sort()
light, heavy = 0, len(people) - 1
while light <= heavy:
if people[light] + people[heavy] > limit:
heavy -= 1
else:
light += 1
heavy -= 1
ans += 1
return ans
class Solution {
public:
int numRescueBoats(vector
return minCount;
}
};
双指针+贪心,要先排序。
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
l, r = 0, len(people) - 1
res = 0
while l < r:
if people[l] + people[r] <= limit:
l += 1
r -= 1
res += 1
else:
r -= 1
res += 1
if l == r:
res += 1
break
return res
时间:O(nlogn) n为peoples长度 空间:O(1)
贪心
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int l = 0, r = people.length - 1, ans = 0;
while (l <= r) {
int tmp = people[r];
--r;
if (l <= r && tmp + people[l] <= limit) {
++l;
}
++ans;
}
return ans;
}
}
Sort greedy
使用语言:Python3
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort(reverse=True)
p1 = 0
p2 = len(people) - 1
count = 0
while p1 <= p2:
if people[p1] == limit:
count += 1
p1 += 1
elif people[p1] + people[p2] > limit:
count += 1
p1 += 1
elif people[p1] + people[p2] <= limit:
count += 1
p1 += 1
p2 -= 1
if p1 == p2:
count += 1
break
return count
复杂度分析 时间复杂度:O(nlogn) 空间复杂度:O(1)
/**
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
res = 0
l = 0
r = len(people) - 1
people.sort()
while l < r:
total = people[l] + people[r]
if total > limit:
r -= 1
res += 1
else:
r -= 1
l += 1
res += 1
if (l == r):
return res + 1
return res
贪心
int numRescueBoats(vector<int>& people, int limit) {
int res = 0;
int left = 0;
right = people.size() - 1;
sort(people.begin(), people.end());
while (left <= right) {
if (people[left] + people[right] > limit)
--right;
else {
++left;
--right;
}
++res;
}
return res;
}
var numRescueBoats = function (people, limit) {
//贪心+双指针
people = people.sort((a, b) => a - b);//升序
let l=0,r=people.length-1,res=0;
while(l<=r){
//这里要包含等于,因为为奇数的时候或者左右指针不是同时前进的时候,相等时的元素也未计算过的元素
//如果左右步数一致,最后一步的时候 l>r自然就退出了 不会重复计算
if(people[l]+people[r]<=limit){
l++;
r--;
}else{
r--
}
res++
}
return res;
};
时间复杂度:O(nlogn) 空间复杂度:O(logn)
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int minCount = 0;
const int len = people.size();
int left = 0, right = len - 1;
// while的条件使用<= 是因为体重可能有重复的
while (left <= right) /* 贪心的方向: 每个船最多装2个人. 根据这个限制我们每次用1个船装最大的1个之后,看看还能不能再装1个, 再装1个最小的即可 */
{
if (people[left] + people[right] <= limit)
{
left++;
right--;
}
else right--;
minCount++;
}
return minCount;
}
};
时间复杂度:O(nlogn)
空间复杂度:O(logn)
class Solution(object):
def numRescueBoats(self, people, limit):
"""
:type people: List[int]
:type limit: int
:rtype: int
"""
people.sort(reverse = True)
l = 0
count = 0
r = len(people)-1
while l<r:
if people[l] + people[r] <= limit:
count += 1
l += 1
r -= 1
else:
count += 1
l += 1
if l==r:
return count+1
return count
时间复杂度:O(nlogn) 空间复杂度:O(1)
// 贪心 11-15
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
int len = people.size();
sort(people.rbegin(), people.rend());
int ans = 0;
int rt = len - 1;
int lf = 0;
while(lf <= rt) {
if ((people[lf] + people[rt]) <= limit) {
ans += 1;
lf += 1;
rt -= 1;
}
else {
ans += 1;
lf += 1;
}
}
return ans;
}
};
const arr = [2, 3, 3, 7, 4, 8, 3, 3]
const limit = 9; //
let temp = arr.sort();
let end = temp.length - 1
let start = 0;
let tA = 0
while (start <= end) {
if (temp[start] + temp[end] <= limit) {
start++
end--
} else {
end--
}
tA++
}
console.log(tA) // 5
时间复杂度:O(nlogn) 空间复杂度:O(1)
对人的体重数组进行升序排序,并使用头尾双指针对撞扫描, 每次计算双指针指向的体重和,如果不超过limit
,则代表两个人都可以装载,否则优先装载较重的那个人(贪心思维体现于此)
/**
* @param {number[]} people
* @param {number} limit
* @return {number}
*/
var numRescueBoats = function(people, limit) {
people.sort((a , b) => a - b);
let smaller = 0 , larger = people.length - 1;
let ans = 0;
let sum;
while(smaller <= larger) {
sum = people[larger] + people[smaller]
if (sum <= limit) {
larger--;
smaller++;
}else{
larger--;
}
ans++;
}
return ans;
};
时间复杂度: O(n)
额外空间复杂度: O(1)
排序
, 贪心
func numRescueBoats(people []int, limit int) int {
sort.Ints(people)
ans, light, heavy := 0 , 0, len(people) - 1
for light <= heavy {
// 如果轻的能和重的一起走,就一起走,否则就重的走
if people[light] + people[heavy] > limit{
heavy --
} else {
light ++
heavy --
}
ans ++
}
return ans
}
var numRescueBoats = function(people, limit) {
people.sort((a,b)=>a-b);
let start = 0 , end = people.length - 1,res = 0;
while(start<=end){
if(people[start]+people[end]<=limit){
start ++;
end--;
}else{
end--;
}
res ++;
}
return res;
};
贪心
def numRescueBoats(self, people: List[int], limit: int) -> int:
ans = 0
people.sort()
light, heavy = 0, len(people) - 1
while light <= heavy:
if people[light] + people[heavy] > limit:
heavy -= 1
else:
light += 1
heavy -= 1
ans += 1
return ans
时间复杂度 O(NlogN) 空间复杂度 O(logN)
881. 救生艇
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/boats-to-save-people/
前置知识
暂无
题目描述
第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。
返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
示例 1:
输入:people = [1,2], limit = 3 输出:1 解释:1 艘船载 (1, 2) 示例 2:
输入:people = [3,2,2,1], limit = 3 输出:3 解释:3 艘船分别载 (1, 2), (2) 和 (3) 示例 3:
输入:people = [3,5,3,4], limit = 5 输出:4 解释:4 艘船分别载 (3), (3), (4), (5) 提示:
1 <= people.length <= 50000 1 <= people[i] <= limit <= 30000