算法题

20 阅读5分钟

算法题

  1. 两数之和

// 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))
  1. 三数之和
    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))
  1. 是否是环形链表
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;
}
  1. 删除有序数组中的重复项

// 题目:原地删除排序数组的重复项,返回新长度。

// 示例: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. 反转链表

// 题目:反转单链表。 // 示例: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

  1. 盛最多水的容器
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. 查找共同 字母异位词

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

示例 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))
  1. 判断一组区间中是否存在任意重叠
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. 查找缺失数字

// [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;
}