js leecode算法记录( 双指针)
分发饼干
题目:假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
注意:
你可以假设胃口值为正。
一个小朋友最多只能拥有一块饼干。
示例 1:
输入: [1,2,3], [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。
示例 2:
输入: [1,2], [1,2,3]
输出: 2
解释:
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.
思路:排序加双指针
先对孩子和饼干数组进行升序排序,然后定义两个指针,i=0,j=0,判断s[j]是否大于等于g[i],如果大于等于,那么更新count++(成功的数量),
i++(寻找下一个孩子),j++(寻找下一个饼干),如果是s[j]小于g[i],那么j++
代码:
var findContentChildren = function(g, s) { g.sort((a,b)=>a-b) s.sort((a,b)=>a-b) let i=0 let j=0 let count=0 while(i<g.length&&j<s.length){ if(s[j]>=g[i]){ count++ i++ j++ }else{ j++ } } return count };
三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
代码
测试用例
测试用例
测试结果
15. 三数之和
已解答
中等
相关标签
相关企业
提示
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
思路:先升序排序,遍历数组,拿到基础点i,定义两个指针,l=i+1
r=nums.length-1
求得三数之和,如果等于0,就更新result数组,如果大于0,r–左移,如果小于0,l++右移,注意要去重,当前基础点nums[i]==nums[i-1]时,continue,跳过该循环,那两个指针也一样,nums[l]==nums[l-1],
nums[r]==nums[r-1]
代码:
`var threeSum = function(nums) {
if (nums.length < 3) {
return [];
}
nums.sort((a, b) => a - b);
let result = [];
for (let i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
let l = i + 1;
let r = nums.length - 1;
while (l < r) {
if (l > i + 1 && nums[l] == nums[l - 1]) {
l++;
continue;
}
if (r < nums.length - 1 && nums[r] == nums[r + 1]) {
r--;
continue;
}
let sum = nums[i] + nums[l] + nums[r];
if (sum > 0) {
r--;
} else if (sum < 0) {
l++;
} else {
result.push([nums[i], nums[l], nums[r]])
l++;
r--;
}
}
}
return result;
}`
524. 通过删除字母匹配到字典里最长单词
给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。
如果答案不止一个,返回长度最长且字母序最小的字符串。如果答案不存在,则返回空字符串。
示例 1:
输入:s = “abpcplea”, dictionary = [“ale”,“apple”,“monkey”,“plea”]
输出:“apple”
示例 2:
输入:s = “abpcplea”, dictionary = [“a”,“b”,“c”]
输出:“a”
思路:遍历数组,拿到每一项之后d[i],定义两个指针l,r,对字符串和单词进行匹配,如果是s[l]==d[r],l和r均右移,如果不相等l++
判断r是否等于d[i].length,说明匹配成功,然后根据单词长度去更新res变量
最后返回res即可
代码:
var findLongestWord = function(s, dictionary) { let res="" let max=-Infinity for(let i=0;i<dictionary.length;i++){ let b=dictionary[i] let a=0; let j=0; while(a<s.length&&j<b.length){ if(s[a]==b[j]){ a++ j++ }else{ a++ } } if(j==b.length){ if(b.length>max|| (b.length === res.length && b < res)){ max=b.length res=b } } } return res };
搜索二维矩阵 II-240
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30],
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
思路:双指针
当一个单元格的值大于target的时候,可以往左找或者往上找,如果小于target的时候可以往右找或者往下找,这样就可以设置row=matrix.length-1,column=0,当单元格大于target,让row–,小于target,就让column–,找到就返回true,循环结束,找不到就返回false(这样就可以设置row=0,column=matrix[0].length-1,当单元格大于target,让column–,小于target,就让row++,找到就返回true,循环结束,找不到就返回false)
代码:
var searchMatrix = function(matrix, target) {
let row=matrix.length-1
let column=0
let x=matrix[0].length
while(row>=0&&column<x){
if(matrix[row][column]>target){
row--
}else if(matrix[row][column]<target){
column++
}else{
return true
}
}
return false
};
283. 移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:你能尽量减少完成的操作次数吗?
思路:定义两个指针,j=0(指向代填充的下标),i=0,循环nums数组,找到不为值0的值,然后把该值填充到j指向的下标的位置,等到遍历完成时,该数组所有非0的数字都被放在左边了,然后遍历j到j,
j<nums.length,填充nums[j]=0
代码:
var moveZeroes = function(nums) {
let j=0
for(let i=0;i<nums.length;i++){
if(nums[i]!==0){
nums[j]=nums[i]
j++
}
}
while(j<nums.length){
nums[j]=0
j++
}
}
优化代码,定义两个指针,只需要把非0的值和0交换即可
var moveZeroes = function(nums) {
let j=0
for(let i=0;i<nums.length;i++){
if(nums[i]!==0){
swap(nums,i,j)
j++
}
}
};
function swap(num,i,j){
let tem=num[i]
num[i]=num[j]
num[j]=tem
}
寻找最长数字的字符串,返回下表
例如:12abci345678ds,返回 6
思路:定义两个指针,i=0;j=0,判断res[j]是否为数字,如果是数字,更新index值和最长数字max,如果不是数字,i=j+1
代码:function fn(res){ let i=0; let max=-1 let index=-1 for(let j=0;j<res.length;j++){ if(!isNaN(res[j])){ let t=j-i+1 if(t>=max){ max=t index=i } }else{ i=j+1 } } return index }