算法题
- 两数之和
// 1两数之和(Two Sum)
// 题目:在数组中找到两个数,使它们的和等于目标值。
// 示例:nums = [2, 7, 11, 15], target = 9 → 返回 [0, 1](因为 2 + 7 = 9)
function add(array,target) {
let newMap = {}
let bb = []
for(let i =0;i<array.length;i++) {
let current = target - array[i]
if(current in newMap) {
bb.push([newMap[current],i])
}
newMap[array[i]] = i
}
return bb
}
console.log(add([1,2,3,4], 5))
- 三数之和
let result = []
nums.sort((a,b)=>a-b)
for(let i =0; i<nums.length-2;i++){
if(i>0 &&nums[i] === nums[i-1]) continue
let left = i+1
let right = nums.length-1
while(left<right){
let sum = nums[i]+nums[left]+nums[right]
if(sum === target){
result.push([nums[i],nums[left],nums[right]])
while(left<right&&nums[left]===nums[left+1]) left++
while(left<right&&nums[right]===nums[right-1]) right++
left++
right--
}else if(sum<target){
left++
} else {
right--
}
}
}
return result
}
console.log(three([-3,-2,-1,0,1,2,3],0))
- 是否是环形链表
function iscircle (head) {
if(!head) {
return false;
}
let slow = head;
let fast = head.next;
while(fast && fast.next) {
if (slow === fast) {
return true;
}
slow = slow.next;
fast = fast.next.next;
}
return false;
}
- 删除有序数组中的重复项
// 题目:原地删除排序数组的重复项,返回新长度。
// 示例:nums = [1, 1, 2] → 返回 2(数组变为 [1, 2, _])
function removeDuplicates(nums) {
let slow = 0; // 慢指针
for (let fast = 1; fast < nums.length; fast++) { // 快指针遍历
if (nums[fast] !== nums[slow]) { // 发现新元素
slow++; // 慢指针移动
nums[slow] = nums[fast]; // 更新数组
}
}
return slow + 1; // 新长度
}
5.有效的括号(Valid Parentheses)
// 题目:判断字符串中的括号是否有效匹配。
// 示例:s = "()[]{}" → 返回 true
function isValid(s) {
const stack = []; // 栈
const map = { ')': '(', ']': '[', '}': '{' }; // 右括号到左括号的映射
for (const char of s) {
if (!map[char]) { // 如果是左括号
stack.push(char); // 入栈
} else if (stack.pop() !== map[char]) { // 右括号需匹配栈顶
return false;
}
}
return stack.length === 0; // 栈为空则全部匹配
}
var isValid = function(s) {
let arr = s.split('')
let newArr = []
for(let i=0;i<arr.length;i++){
if(arr[i]=== '('|| arr[i]==='['||arr[i]==='{'){
newArr.push(arr[i])
} else {
if(newArr.length === 0) return false
let top = newArr.pop()
if(arr[i]=== ')' && top !== '('
|| arr[i]=== ']' && top !== '['
|| arr[i]=== '}' && top !== '{'
){
return false
}
return newArr.length === 0
}
}
};
- 反转链表
// 题目:反转单链表。 // 示例:1 -> 2 -> 3 -> null → 返回 3 -> 2 -> 1 -> null
function reverseList(head) {
let prev = null;
let curr = head;
while (curr) {
const next = curr.next; // 暂存下一个节点
curr.next = prev; // 反转指针
prev = curr; // prev 前进
curr = next; // curr 前进
}
return prev; // 新头节点
}
7.判断字母异位图
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram" 输出: true 示例 2:
输入: s = "rat", t = "car" 输出: false
- 盛最多水的容器
var maxArea = function(height) {
var left = 0
var right = height.length -1
var max = 0
if(height[left] < height[right] ) {
left++
} else {
right--
}
area = Math.min(height[left],height[right]) * (right-left)
max = Math.max(max, area)
console.log('max',max)
return max
};
console.log(maxArea([1,8,6,2,5,4,8,3,7]))
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
将所有数字存入一个哈希集合中,以便快速查找。
遍历数组中的每一个数字:
如果当前数字的前一个数字(即 num - 1)存在于集合中,说明当前数字不是某个连续序列的起点,跳过。
否则,当前数字是一个连续序列的起点,开始向后查找连续的数字(即 num + 1、num + 2 等),直到找不到连续的数字为止,记录当前序列的长度。
在所有序列中,记录最长的长度。
var longestConsecutive = function(nums) {
let set = new Set(nums)
let long = 1
for(i of set) {
if(!set.has(i-1)){
var currentNum = i
var currentCount = 1
while(set.has(currentNum+1)){
currentNum++
currentCount++
}
}
long = Math.max(long,currentCount)
}
return long
};
console.log(longestConsecutive([100,4,101,1,3,2]))
console.log(longestConsecutive([0,3,7,2,5,8,4,6,0,1]))
10.字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram" 输出: true 示例 2:
输入: s = "rat", t = "car" 输出: false
11."只出现一次的数字"
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。要求找出那个只出现了一次的元素。
12."多数元素"
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊n/2⌋ 的元素。
var majorityElement = function(nums) {
var map = {}
nums.forEach((item)=>{
if(item in map){
map[item]++
} else {
map[item] = 1
}
})
let len = nums.length/2
for(let i in map) {
if(map[i]>len){
return i
}
}
};
console.log(majorityElement([3,2,3]))
- 查找共同 字母异位词
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
示例 1: 输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
解释:
在 strs 中没有字符串可以通过重新排列来形成 "bat"。 字符串 "nat" 和 "tan" 是字母异位词,因为它们可以重新排列以形成彼此。 字符串 "ate" ,"eat" 和 "tea" 是字母异位词,因为它们可以重新排列以形成彼此。
初始化一个空字典 anagram_groups,用于存储分组。
遍历 strs 中的每一个字符串 s:
将 s 排序,得到排序后的字符串 sorted_s。
如果 sorted_s 不在 anagram_groups 的键中,则添加 sorted_s 作为键,并将 [s] 作为值。
如果 sorted_s 已经在 anagram_groups 的键中,则将 s 添加到对应的值列表中。
最后,将字典中的所有值转换为列表并返回。
function groupAnagrams(strs) {
const anagramGroups = {};
for (const s of strs) {
const sorted = s.split('').sort().join('');
if (!anagramGroups[sorted]) {
anagramGroups[sorted] = [];
}
anagramGroups[sorted].push(s);
}
return Object.values(anagramGroups);
}
var strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
console.log(groupAnagrams(strs))
- 判断一组区间中是否存在任意重叠
function hasOverlappingIntervals(intervals) {
if (intervals.length <= 1) return false;
// 按区间起始点排序
intervals.sort((a, b) => a[0] - b[0]);
console.log('intervals',intervals)
for (let i = 1; i < intervals.length; i++) {
// 如果当前区间的起始点小于前一个区间的结束点,则存在重叠
if (intervals[i][0] < intervals[i-1][1]) {
return true;
}
}
return false;
}
// 测试示例
console.log(hasOverlappingIntervals([[1,4],[5,7],[2,6]])); // true (区间[1,4]和[2,6]重叠)
console.log(hasOverlappingIntervals([[1,4],[5,7],[8,10]])); // false (所有区间不重叠)
- 查找缺失数字
// [1,2,4,0] 找出来3 // [2,1]找出来0 // [1,2,4,7,5,8]找出来0,3,6,
function findMissingNumbers(arr) {
if (!arr || arr.length === 0) return [];
const min = Math.min(...arr);
const max = Math.max(...arr);
const set = new Set(arr);
const missing = [];
for (let i = min; i <= max; i++) {
if (!set.has(i)) {
missing.push(i);
}
}
return missing;
}