Open azl397985856 opened 2 years ago
class Solution: def numRescueBoats(self, people: List[int], limit: int) -> int: people.sort()
ct = 0
l =0
r = len(people)-1
while l<=r:
if people[l] + people[r] <=limit:
l+=1
r-=1
ct +=1
else:
r-=1
ct+=1
return ct
class Solution:
def numRescueBoats(self, ls: List[int], limit: int) -> int:
ls.sort()
l , r = 0 , len(ls)-1
ans = 0
while l <= r:
if ls[l] + ls[r] <= limit:
l += 1
r -= 1
ans += 1
return ans
题目链接: 881. 救生艇 https://leetcode-cn.com/problems/boats-to-save-people/
排序 + 双指针 + 贪心。
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
ans = 0
left, right = 0, len(people)-1
while left<right:
ans += 1
if people[left] + people[right] <= limit:
left += 1
right -= 1
if left == right:
return ans + 1
return ans
复杂度分析
思路 排序,贪心 最大最小能凑一对就一起走,不能就大的单走,再检测下一对
代码
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
if people[-1] > limit:
return -1
l = 0
r = len(people) - 1
count = 0
while l <= r:
if people[l] + people[r] <= limit:
l += 1
r -= 1
count += 1
return count
复杂度 时间 O(nlogn) 空间 O(logn)
排序,然后左右结合取数,证明就是1,2,3,4 1和4尽量走,而不是4和2尽量走,因为2,4可以走,那么2,3一定可以走,贪心啊。。 思路大于代码,思路想到了代码很好实现,当然这种问题不能临场证明,应该提取背下来
class Solution {
// 排序,然后左右结合取数,证明就是1,2,3,4 1和4尽量走,而不是4和2尽量走,因为2,4可以走,那么2,3一定可以走,贪心啊。。
//
public int numRescueBoats(int[] people, int limit) {
int result = 0;
int r = people.length - 1;
int l = 0;
Arrays.sort(people);
while (l <= r) {
if (l == r) {
result++;
break;
}
if (people[r] + people[l] > limit) {
result++;
r--;
} else {
result++;
r--;
l++;
}
}
return result;
}
}
复杂度分析
贪心。
尽可能多一船带走更多人。
方法一:
统计每个体重的人的数量。
然后对于每个体重 w,检索 limit - w,如果检索到了,对应人数各扣减 1。如果找不到的话,那么比检索目标更小的体重也是符合要求的,直到最小体重为止。
重复上述过程直到所有人数都有船坐。
时间复杂度 O(limit^2)
空间复杂度 O(n) n 为people 长度。
方法二: 双指针
将数组排序,左右指针指向最小和最大,如果 l + r > limit ,则大的那个体重独占一艘船,否则,两人共用一艘船。
时间复杂度 O(n log n)
空间复杂度 O(log n)
class Solution:
def numRescueBoats1(self, people: List[int], limit: int) -> int:
freq = Counter(people)
ans = 0
for w in range(1, limit + 1):
while w in freq:
ans += 1
freq[w] -= 1
if freq[w] == 0:
del freq[w]
for s in range(limit - w, 0, -1):
if s in freq:
freq[s] -= 1
if freq[s] == 0:
del freq[s]
break
return ans
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
l,r,boats=0,len(people)-1,0
while l<r:
if people[l]+people[r] >limit:
r-=1
boats+=1
continue
l+=1
r-=1
boats+=1
return boats+1 if l ==r else boats
贪心 排序+双指针
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int n = people.length;
int l = 0, r = n - 1;
int count = 0;
while(l <= r){
if(people[l] + people[r] > limit){
r--;
}else{
l++;
r--;
}
count++;
}
return count;
}
}
复杂度分析
贪心 让每艘船浪费的运力最小
def numRescueBoats(self, people: List[int], limit: int) -> int:
people=sorted(people)
res,l,r=0,0,len(people)-1
while l<=r:
if l!=r and people[l]+people[r]<=limit:
l+=1
r-=1
res+=1
return res
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
l, r = 0, len(people) - 1
ans = 0
while l <= r:
if people[l] + people[r] <= limit:
l += 1
r -= 1
else:
r -= 1
ans += 1
return ans
Java Code:
class Solution {
public int numRescueBoats(int[] people, int limit) {
int num = 0;
int left = 0;
int right = people.length-1;
Arrays.sort(people);
while(left<=right){
if(people[left]+people[right] <= limit) left++;
right--;
num++;
}
return num;
}
}
class Solution {
public:
int numRescueBoats(vector
int left = 0, right = people.size() - 1;
int res = 0;
while (left <= right) {
if (left == right) {
++res;
break;
}
if (people[left] + people[right] > limit) {
++res;
--right;
} else {
++res;
++left;
--right;
}
}
return res;
}
};
Greedy + sort
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
int ans = 0;
int j = people.size()-1;
sort(people.begin(), people.end());
for(int i = 0; i< people.size(); i++){
if(people[i] == 0) continue;
int p1 = limit - people[i];
while(j>i and people[j]>p1) j--;
if(j>i and people[j] !=0){
people[j] = 0;
j--;
}
ans+=1;
}
return ans;
}
};
Time: O(N log N) Space: O(1)
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:
def numRescueBoats(self, people: List[int], limit: int) -> int:
ans = len(people)
people.sort()
i, j = 0, len(people) - 1
while i < j:
if people[i] + people[j] <= limit:
ans -= 1
i += 1
j -= 1
else:
j -= 1
return ans
# 贪心:设 \textit{people}people 的长度为 nn。考虑体重最轻的人:
# 若他不能与体重最重的人同乘一艘船,那么体重最重的人无法与任何人同乘一艘船,此时应单独分配一艘船给体重最重的人。从 \textit{people}people 中去掉体重最重的人后,我们缩小了问题的规模,变成求解剩余 n-1n−1 个人所需的最小船数,将其加一即为原问题的答案。
# 若他能与体重最重的人同乘一艘船,那么他能与其余任何人同乘一艘船,为了尽可能地利用船的承载重量,选择与体重最重的人同乘一艘船是最优的。从 \textit{people}people 中去掉体重最轻和体重最重的人后,我们缩小了问题的规模,变成求解剩余 n-2n−2 个人所需的最小船数,将其加一即为原问题的答案。
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
# mini num of boat.
# each boat at most 2 idx. weight sum < limit.
res = 0
people.sort()
light, heavy = 0, len(people) - 1
while light <= heavy:
if people[light] + people[heavy] <= limit:
res += 1
light += 1
heavy -= 1
else:
res += 1
heavy -= 1
return res
Time: O(nlogn) sort Space: O(logn) sort
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
if people[-1] > limit:
return -1
l = 0
r = len(people) - 1
count = 0
while l <= r:
if people[l] + people[r] <= limit:
l += 1
r -= 1
count += 1
return count
func numRescueBoats(people []int, limit int) (ans int) {
n:= len(people)
if n == 0{
return 0
}
sort.Slice(people, func(i, j int) bool { return people[i]<people[j]})
l:=0
r:=n-1
for r>=0 {
if people[r] == limit{
ans++
r--
}else {
break
}
}
for l<=r{
if l == r{
ans++
break
}
if people[l] + people[r] > limit{
ans++
r--
}else {
ans++
l++
r--
}
}
return ans
}
func numRescueBoats(people []int, limit int) int {
sort.Ints(people)
out := 0
l,r := 0,len(people)-1
for l <= r{
temp := limit
temp -= people[r]
r--
if temp >= people[l]{
l++
}
out++
}
return out
}
思路
贪心算法。先按大小排序,两个指针分别指头尾,如果大的+小的超过limit,则大的只能单独放。
代码
function numRescueBoats(people: number[], limit: number): number {
let res = 0;
const n = people.length;
people.sort((a, b) => a - b);
let left = 0, right = n - 1;
while(left <= right){
if(people[left] + people[right] <= limit){
left++;
};
right--;
res++;
};
return res;
};
复杂度分析
class Solution {
public int numRescueBoats(int[] people, int limit) {
if (people.length == 1) {
return 1;
}
Arrays.sort(people);
int low = 0;
int high = people.length - 1;
int count = 0;
while (low <= high) {
if (people[low] + people[high] <= limit) {
low++;
high--;
} else {
high--;
}
count++;
}
return count;
}
}
var numRescueBoats = function (people, limit) {
people.sort((a, b) => a - b);
let ans = 0,
start = 0,
end = people.length - 1;
while (start <= end) {
if (people[end] + people[start] <= limit) {
start++;
end--;
} else {
end--;
}
ans++;
}
return ans;
};
时间复杂度:O(nlogn)O(nlogn)
空间复杂度:O(1)O(1)
class Solution(object):
def numRescueBoats(self, people, limit):
"""
:type people: List[int]
:type limit: int
:rtype: int
"""
people.sort()
ans, l, r = 0, 0, len(people) - 1
while(l <= r):
if people[l] + people[r] <= limit:
l += 1
r -= 1
else:
r -= 1
ans += 1
return ans
var numRescueBoats = function(people, limit) {
people.sort((a, b) => a - b)
let j = people.length - 1
let i = 0
let ans = 0
while (i < j) {
if (people[j] + people[i] > limit) {
j --
} else {
j --
i ++
}
ans ++
}
if (i === j) {
ans ++
}
return ans
};
code:
class Solution {
public int numRescueBoats(int[] people, int limit) {
int res = 0;
int l = 0;
int r = people.length - 1;
Arrays.sort(people);
while (l <= r) {
if (l == r) {
res++;
break;
}
if (people[r] + people[l] > limit) {
res++;
r--;
} else {
res++;
r--;
l++;
}
}
return res;
}
}
思路
所需最小船数==>每艘船尽量装2个人,装更多重量(子问题)==>排序体重数组
子问题:先选择最重people,再选择最轻的体重,判断能否装进船里;
A:最重;B:余下非最轻;C:最轻;D:余下任一
为什么第二个人要选最轻的,而不是选择余下其他重量的匹配?
如果第二个人B选择其他重量
A,B可以匹配入船A+B<=limit,C<B&&D<A ==> C+D<=limit 则(A,B)(C,D)两艘船;交换B,C则A+C<=limit, D+B <= limit则(AC)(BD)也可以使用两艘船;不影响结果
两个人不匹配,为保证船尽量装2人,则应当查询较轻的人去匹配A直到匹配最轻的人;
所以,直接选择最轻的人对最优解无影响;
步骤
1. 数组升序排序;
2. 左右指针left,right;选择right指针元素,判断left指针元素和是否小于limit;
3. 小于,ans++且left++,right--;
4. 大于,right--;
5. 返回ans;
java code
class Solution {
public int numRescueBoats(int[] people, int limit) {
int n = people.length;
Arrays.sort(people);
int left = 0,right = n - 1,res = 0;
while(left<=right){
if(people[left] + people[right] <= limit){
left++;
right--;
}else{
right--;
}
res++;
}
return res;
}
}
时间:$O(nlogn)$
空间:$O(logn)$
贪心,让体重大的先上船。如果船上还有位置,再上一个体重小的。
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int low = 0;
int high = people.length - 1;
int total = 0;
while (low <= high) {
total++;
if (limit - people[high] >= people[low]) {
low++;
}
high--;
}
return total;
}
}
TC: O(N LogN) SC: O(1)
贪心, 排序 + 双指针
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
ans = 0
start = 0
end = len(people) - 1
while start < end:
if people[end] + people[start] > limit:
ans += 1
end -= 1
else:
end -= 1
start += 1
ans += 1
if start == end:
return ans + 1
return ans
思路: 贪心 + 双指针
复杂度分析:
代码(C++):
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int res = 0;
int l = 0, r = people.size() - 1;
while (l <= r) {
if (people[r] + people[l] <= limit) {
l++;
}
++res;
r--;
}
return res;
}
};
C++ Code:
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int left =0;
int right = people.size()-1;
int ret =0;
while(left<=right)
{
if(left!=right && (people[left]+people[right])<=limit)
{
ret++;
left++;
right--;
}
else
{
ret++;
right--;
}
}
return ret;
}
};
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;
}
}
越重的人,越容易自己独占一条船。如果想尽可能地利用空间,就尽可能往它们上面塞人。 排序后,双指针。如果两人的和小于等于limit,那么左右凑一对儿,往中间递归;否则右边独自占一条船。 def numRescueBoats(self, people: List[int], limit: int) -> int: n = len(people) people.sort() left, right = 0, n - 1 res= 0 while left <= right: if people[left] + people[right] <= limit: left += 1 right -= 1 res+= 1 return res
贪心
var numRescueBoats = function (people, limit) {
let res = 0;
let p = 0;
let q = people.length - 1;
people.sort((a, b) => a - b);
while (p <= q) {
if (people[q] + people[p] <= limit) {
p++;
}
q--;
res++;
}
return res;
};
时间复杂度:O(nlogn)
空间复杂度:O(logn)
class Solution:
def numRescueBoats(self, people: List[int], limit: int) -> int:
people.sort()
l, r = 0, len(people) - 1
ans = 0
while l <= r:
if people[l] + people[r] <= limit:
ans += 1
l += 1
r -= 1
else:
ans += 1
r -= 1
return ans
Time complexity O(nlogn) Space complexity O(1)
C++ Code:
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
if (people.empty()) {
return 0;
}
int res = 0;
sort(people.begin(), people.end());
int left = 0, end = people.size() - 1;
while (left <= end) {
if (people[left] + people[end] <= limit) {
++left;
--end;
} else {
--end;
}
++res;
}
return res;
}
};
排序+双指针+贪心
怎么贪心?一左一右成组,能送就送,不能送就单独送大的(因为people最重重不过limit)
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(),people.end());
int l = 0;
int r = people.size()-1;
int count = 0;
while(l<=r){
if(l!=r&&people[l]+people[r]<=limit){
l++;
}
r--;
count++;
}
return count;
}
};
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
双指针 贪心
var numRescueBoats = function(people, limit) {
let len = people.length
people.sort((a,b)=> a-b)
let light = 0
let heavy = len-1
let ans = 0
while(light<=heavy) {
if (people[light] + people[heavy] <= limit) {
light++
}
heavy--
ans++
}
return ans
}
时间复杂度:O(nlogn)
空间复杂度:O(1)
贪心
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int len = people.length;
int l = 0;
int r = len - 1;
int res = 0;
while (r >= l) {
int temp = limit - people[r--];
if (temp >= people[l]) {
l++;
}
res++;
}
return res;
}
}
时间复杂度:O(nlogn) 空间复杂度:O(1)
class Solution { public int numRescueBoats(int[] people, int limit) { int result = 0; int r = people.length - 1; int l = 0; Arrays.sort(people); while (l <= r) { if (l == r) { result++; break; }
if (people[r] + people[l] > limit) {
result++;
r--;
} else {
result++;
r--;
l++;
}
}
return result;
}
}
选择头尾两个人。如果可以同时载就运载这两个人。如果不可行,那么这个重的人和剩下任何人都无法配对,只能自己走了。
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int left =0;
int right = people.size()-1;
int count =0;
while(left <=right)
{
if(left!=right && people[right]+people[left]<=limit)
{
right--;
left++;
count++;
}
else
{
right--;
count++;
}
}
return count;
}
};
贪心
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;
}
}
Time O(nlogn) Space O(nlogn)
贪心,每次都运最重的人,看有没有人可以跟他搭配
class Solution(object):
def numRescueBoats(self, people, limit):
"""
:type people: List[int]
:type limit: int
:rtype: int
"""
people.sort(reverse = True)
ans = 0
l = 0
r = len(people)-1
while l < r :
if people[l] + people[r] <= limit:
r -= 1
l += 1
ans += 1
if (l == r):
return ans+1
return ans
时间复杂度:O(nlogn) 空间复杂度:O(1)
贪心
public class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int ans = 0;
int left = 0, right = people.length - 1;
while (left <= right){
if (people[left] + people[right] <= limit){
left++;
}
right--;
ans++;
}
return ans;
}
}
复杂度分析
排序 + 双指针
因为船只能搭两个人,一大一小的搭配是最合适的。 排序之后就变成了求和问题了。
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int left = 0;
int right = people.size() - 1;
int ans = 0;
while (left <= right) {
if (people[right] >= limit) { // cover two situation > and ==, both can happen
right--;
ans++;
} else if (people[left] + people[right] > limit) {
right--;
ans++;
} else if (people[left] + people[right] <= limit) {
left++;
right--;
ans++;
}
}
return ans;
}
};
**复杂度分析**
- 时间:O(nlogn),排序时间最长
- 空间:O(1)
思路 排序 + 双指针
class Solution { public int numRescueBoats(int[] people, int limit) { Arrays.sort(people); int left = 0; int right = people.length - 1; int res = 0;
while (left <= right) {
res++;
if (people[left] + people[right] <= limit) {
left++;
}
right--;
}
return res;
}
}
时间复杂度:O(nlogn) 空间复杂度:O(1)
思路: 排序 贪心
func numRescueBoats(people []int, limit int) int {
sort.Ints(people)
left,right := 0,len(people) - 1
ans := 0
for left <= right {
if people[left] + people[right] > limit {
right --
}else {
left ++
right --
}
ans ++
}
return ans
}
贪心算法,重的人先乘
class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int n = people.length, count = 0, i = n-1, j = 0;
while (i >= 0 && j < n && j <= i){
if(j == i) {
count++;
break;
}
if(people[i] + people[j] <= limit) {
count++;
i--;
j++;
} else {
count++;
i--;
}
}
return count;
}
}
O(N)
贪心
public class Solution {
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int ans = 0;
int left = 0, right = people.length - 1;
while (left <= right){
if (people[left] + people[right] <= limit){
left++;
}
right--;
ans++;
}
return ans;
}
}
var eraseOverlapIntervals = function(intervals) {
let len = intervals.length;
if(len==0) return 0;
//通过区间最后一个元素排序
intervals.sort((a,b)=>a[1]-b[1]);
//最多不重叠区间数,至少为1
let count = 1;
//初始结尾
let end= intervals[0][1];
for(let inter of intervals){
let num = inter[0];
if(num>=end){
count++;
end = inter[1];
}
}
return len-count;
};
var numRescueBoats = function(people, limit) {
people.sort((a,b)=>(a-b))
let left = 0
let right = people.length-1
let nums=0
while(left<=right){
if(people[left]+people[right]<=limit){
left++
}
right--
nums++
}
return nums
};
Codes var numRescueBoats = function(people, limit) { people.sort((a,b)=>(a-b)) let left = 0 let right = people.length-1 let nums=0 while(left<=right){ if(people[left]+people[right]<=limit){ left++ } right-- nums++ } return nums };
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