1. 无重复字符的最长子串
var lengthOfLongestSubstring = function(s) {
let l = 0; // 定义左指针
let r=0
let res = 0; // 结果
let map = new Map(); // 存放字符和对应下标
let len = s.length
while (r<len) {
// 两个重复的情况 所以要 map.get(s[r]) >= l
if (map.has(s[r]) && map.get(s[r]) >= l) {
l = map.get(s[r]) + 1; // 出现重复 取其下一个 出现重复的和最后边的重复了 就取其下一个正好
}
res = Math.max(res, r - l + 1); // 计算结果 ab 字符串是1-0+1
map.set(s[r], r); // 存下每个字符的下标
r++
}
return res;
};
15. 最长回文子串
var longestPalindrome = function(s) {
let start =0;
let end =0;
let maxLen = 0
// 从中间扩散到两边 一直相等一直变长
function getOther(left, right){
while (left>=0&&right<s.length&&s[left]===s[right]){
left--;
right++;
}
// 进来基数时候进来就会进循环 偶数时候不相等也默认是1
return right - left - 1
}
for(let i=0;i<s.length;i++){
// 考虑奇数偶数
const len1 = getOther(i, i);// 奇数
const len2 = getOther(i, i+1)// 偶数
const len = Math.max(len1,len2)
if(maxLen<len){
maxLen = len
start = i - Math.floor((len-1)/2)// 奇数的时候 向前len-1的一半********
end = i + Math.floor(len/2)
}
}
return s.substring(start,end+1)
};
4. 比较版本号
版本号特点是字符串的。用.分开的字符串。从高位到底位只要大就大 和 字符串的总长度无关
var compareVersion = function(version1, version2) {
// map(NUmber) 直接转换成number的数组 可以直接比较;大于小于的时候直接返回;循环完没有返回则返回0
var v1 = version1.split('.').map(Number)
var v2 = version2.split('.').map(Number)
var vm = Math.max(v1.length, v2.length)
for(let i=0;i<vm;i++){
if((v1[i]||0)>(v2[i]||0)){
return 1;
}
if((v1[i]||0)<(v2[i]||0)){
return -1;
}
}
return 0;
};
7. 有效的括号
栈存储左括号,遇到右括号 与之对应则弹出 没有对应返回false;最后栈空则全部匹配
var isValid = function(s) {
const mapping = {
')': '(',
'}': '{',
']': '['
};
let stack = []
for(char of s){
// 如果是左侧存入栈 如果是右侧看是不是和栈顶的一样
if(mapping[char]){
// 如果不一样 返回false 一样的话pop出栈
if(mapping[char] !== stack.pop()){
return false
}
}else {
stack.push(char)
}
}
// 最后栈空 为正好全部匹配
return stack.length === 0
};
8. 字符串相加
进制两个相加时候 从底位开始 取余和删除。注意字符串转成数字相加
var addStrings = function(num1, num2) {
let superfluous = 0;// 默认没有进位
let result = ''// 默认是空字符串
let i=num1.length -1,j=num2.length-1
// i>=0 j>=0 一直循环到最后
while(i>=0||j>=0||superfluous>0){
// ~~(num1[i]||0) 取出来的是字符串 一定要转成number
const sum = ~~(num1[i]||0) + ~~(num2[j]||0) + superfluous
// sum/10 进位的值
superfluous = Math.floor(sum/10)
// sum%10 个位 当前位的值
result = (sum%10) + result
i--;
j--;
}
return result;
};
27. 最大交换 交换完数最大
给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。
只要后边的数「最大数」比前面的数大 移动到前面来就是最大数
var maximumSwap = function(num) {
const numArr = num.toString().split('')
const lastArr = Array(10).fill(-1);
// 存储每个数字的位置
for(let i = 0;i<numArr.length;i++){
lastArr[numArr[i]] = i
}
for(let i=0;i<numArr.length;i++){
// 比当前值大 且位置在当前值后边 遍历9- numarr【ℹ️】 就是找 比他大的数
for(let j=9;j>numArr[i];j--){
if(lastArr[j]>i){
// 交换是交换位置 lastArr[j] 才是j的位置 并不是j
[numArr[i], numArr[lastArr[j]]] = [numArr[lastArr[j]], numArr[i]]
return Number(numArr.join(''))
}
}
}
return num;
};
51. Excel表列名称
var convertToTitle = function(columnNumber) {
let result = ''
while (columnNumber>0){
// 列在0 开始 都要-1
const current =(columnNumber-1)%26;
result = String.fromCharCode(current + 65) + result
columnNumber = Math.floor((columnNumber-1)/26)
}
return result
};
52. Excel 表列序号 相当于26进制
var titleToNumber = function(columnTitle) {
// let result = 0
// let step = 1
// while (columnTitle){
// const end = columnTitle.substring(columnTitle.length-1,columnTitle.length)
// result += step*(end.charCodeAt(0)-64)
// step *=26;
// columnTitle = columnTitle.substring(0,columnTitle.length-1)
// console.log(columnTitle)
// }
// return result;
// uniCode 码; a:97 A:65 ;str.charCodeAt(i)如果不写i 默认取str的unicode
// 最大开始遍历 每次*26。 进制 如果是10进制 就*10
let result = 0;
for (let i = 0; i < columnTitle.length; i++) {
result = result * 26 + (columnTitle.charCodeAt(i) - 64);
}
return result;
};
82.回文数
从低位开始。倒过来
var isPalindrome = function(x) {
if(x<0){
return false
}
let tempX = x
let rt = 0
while (x) {
rt = 10*rt + x%10 // 加上一位。每次加一位 原来的相左移动一位所有*10
x = Math.floor(x/10)// 向右移动 /10
}
if(rt == tempX){
return true
} else {
return false
}
};
70.替换空格
// 注意一点 字符串不是引用类型 直接改的话不会变化;s[2] = '20%' s是不发生变化的;
// 所有用一个字符串一直拼接
function replaceSpace(s){
let rt = ''
for(let i=0,len=s.length;i<len;i++){
if(s[i] === ' '){
rt += '%20'
} else {
rt += s[i]
}
}
return rt;
}
98.写一个算法 实现一个字符串的规则解析:
例子:a(b)<2>c 输出:abbc,a(b(c)<3>de)<2>f 输出abcccdebcccdef;()代表重复内容,<>代表重复的次数
function parseAndRepeat(str) {
let stack = ['']; // 初始化栈,栈底是空字符串,用于累加结果
let i = 0; // 遍历字符串的索引
while (i < str.length) {
let char = str[i];
if (char === '(') {
// 遇到 '(',开始新的重复区块
stack.push('');
i++;
} else if (char === ')') {
// 遇到 ')',结束当前重复区块
let repeatedStr = stack.pop(); // 获取当前重复区块内容
i++;
// 查找重复次数
let repeatTimes = 0;
if (str[i] === '<') {
i++;
let numStart = i;
while (str[i] !== '>') {
i++;
}
repeatTimes = parseInt(str.slice(numStart, i));
i++;
}
stack[stack.length - 1] += repeatedStr.repeat(repeatTimes);
} else {
// 非特殊字符,直接加入当前字符串
stack[stack.length - 1] += char;
i++;
}
}
return stack.join(''); // 将栈中的所有字符串合并
}
// 示例用法
console.log(parseAndRepeat('a(b)<2>c')); // 输出:abbc
console.log(parseAndRepeat('a(b(c)<3>de)<2>f')); // 输出:abcccdebcccdef