【js】-【括号、全排列、子集、字符串相乘、驼峰】-比较好的题记录

本文介绍了多种算法问题的解决方案,包括括号匹配的有效性检查、字符串全排列、子集生成、字符串乘法计算、转驼峰命名以及LRU缓存设计。这些问题涉及到字符串处理、递归、回溯、数据结构和算法设计等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.巧用map 解决括号匹配

描述
给出一个仅包含字符’(‘,’)‘,’{‘,’}‘,’[‘和’]',的字符串,判断给出的字符串是否是合法的括号序列
括号必须以正确的顺序关闭,"()“和”()[]{}“都是合法的括号序列,但”(]“和”([)]"不合法。
数据范围:字符串长度 0\le n \le 100000≤n≤10000
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

示例1
输入:
"()[]{}"
返回值:
true
示例2
输入:
"([)]"
复制
返回值:
false
function isValid( s ) {
    // write code here
    var map=new Map()
    map.set("(",")")
    map.set("{","}")
    map.set("[","]")
    var stack=[]
    for(let i=0;i<s.length;i++){
        if(map.has(s[i]))
            stack.push(map.get(s[i]))
        else{
            if(stack.pop()!==s[i])  return false
        }
    }
    if(stack.length!==0) return false
    return true
}

2 所有排列

描述 输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。

数据范围:n < 10n<10 要求:空间复杂度 O(n!)O(n!),时间复杂度 O(n!)O(n!) 输入描述:
输入一个字符串,长度不超过10,字符只包括大小写字母。

示例1 输入: “ab”
返回值: [“ab”,“ba”]

返回[“ba”,“ab”]也是正确的

示例2 输入: “aab”
返回值: [“aab”,“aba”,“baa”]

function Permutation(str)
{
    // 深度遍历优先DFS及回溯
    //[a] [bc] [cb]
    //    [ab] [c]
    //    [ac] [b]
    let ans=[]
    str= str.split('').sort((a,b)=>{
        return a>b?1:-1
    }).join('') //split('')切成数组 排序 join('')拼接成字符串

    const dfs=(cur,store)=>{ //cur临时字符,store可选字符集
        //1.是否满足条件,记录结果
        //判断终止条件
        if(!store.length) return ans.push(cur) //j没有候选了,结束
        for(let i=0;i<store.length;i++){
            if(i>0&&store[i]===store[i-1]) continue; //去重
            dfs(cur+store[i],store.slice(0,i)+store.slice(i+1)) //下一个
        }
    }
    dfs('',str) //初始 临时字符创为空
    return ans
}
module.exports = {
    Permutation : Permutation
};

3 所有子集

【集合的所有子集】(小米)
问题描述: 集合的所有子集 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集。示例如下:
输入样例1:nums = [1,2,3]
输出样例1:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
输入样例2:nums = [0]
输出样例2:[[],[0]]

输入样例: 1 2 3
输出样例: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

function allSubsets(arr){
	let res = [[]];
	for(let i = 0; i < arr.length; i++){
		const tempRes = res.map(subset => {
			const one = subset.concat([]);
			one.push(arr[i]);
			return one;
		})
		res = res.concat(tempRes);
	}
	return res;
}
var line;
while(line = read_line()){
	let splitLine = line.split(' ')
	print(JSON.stringify(allSubsets(splitLine.map(Number))))
}

4 字符串乘法

【字符串相乘】
问题描述:
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
输入:字符串s
输出:字符串ans
输入样例1:num1 = “1”, num2 = “4”
输出样例1: “4”
输入样例2:num1 = “123”, num2 = “456”
输出样例2: “56088”
说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

var multiply = function(num1, num2) {
if(num1 == 0 || num2 == 0) return "0"
const res = [];// 结果集
for(let i = 0; i < num1.length; i++){
	let tmp1 = num1[num1.length - 1 - i]; // num1尾元素
	for(let j = 0; j < num2.length; j++){
		let tmp2 = num2[num2.length - 1 - j]; // num2尾元素
		let pos = res[i + j] ? res[i + j] + tmp1 * tmp2 : tmp1 * tmp2;// 目标值 ==》三元表达式,判断结果集索引位置是否有值
		res[i+j] = pos%10; // 赋值给当前索引位置
		// 目标值是否大于10 ==》是否进位 这样简化res去除不必要的"0"
		pos >= 10 && (res[i + j + 1] = res[i + j + 1] ? res[i + j + 1]+Math.floor(pos/10) : Math.floor(pos/10));
		}
	}
	return res.reverse().join("");
};
var line;
while(line = read_line()){
	let splitLine = line.split(' ');
	print(multiply(splitLine[0],splitLine[1]))
}

5 转驼峰

border-bottom-color=>borderBottomColor

var str="border-bottom-color";
function tf(){
  var arr=str.split("-");
  for(var i=1;i<arr.length;i++){
    arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substring(1);
  }
  return arr.join("");
};
tf(str);

6 用map对象实现LRU缓存结构

牛客BM100 设计LRU缓存结构

设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 capacity ,操作次数是 n ,并有如下功能:
1. Solution(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
2. get(key):如果关键字 key 存在于缓存中,则返回key对应的value值,否则返回 -13. set(key, value):将记录(key, value)插入该结构,
 如果关键字 key 已经存在,则变更其数据值 value;
 如果不存在,则向缓存中插入该组 key-value ,如果key-value的数量超过capacity,弹出最久未使用的key-value

提示:
1.某个key的set或get操作一旦发生,则认为这个key的记录成了最常使用的,然后都会刷新缓存。
2.当缓存的大小超过capacity时,移除最不经常使用的记录。
3.返回的value都以字符串形式表达,如果是set,则会输出"null"来表示(不需要用户返回,系统会自动输出),方便观察
4.函数set和get必须以O(1)的方式运行
5.为了方便区分缓存里key与value,下面说明的缓存里key用""号包裹


var Solution = function(capacity) {
    this.res=new Map();
    this.capacity=capacity;
};

Solution.prototype.get = function(key) {
    if(this.res.has(key)){
        let value= this.res.get(key);
        this.res.delete(key);
        this.res.set(key,value);
        return value;
    }else return -1;
};
Solution.prototype.set = function(key, value) {
    if(this.res.size===this.capacity){
        let last=this.res.keys().next();
        //删除最“老”的节点,也就是最先插入元素
        //,map.keys产生的是一个迭代器,所以使用next可以获取第一个元素
        this.res.delete(last.value);
    }
    
    this.res.set(key,value);
};

MapObject类型的一个主要差异是,Map实例会维护键值对的插入顺序,因此可以根据插入顺序执行迭代操作。
删除最“老”的节点,也就是最先插入元素,map.keys产生的是一个迭代器,所以使用next可以获取第一个元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值