1.仅仅反转字母
题目:给定一个字符串 S
,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。
思路:双指针法,记录两边的字符串拼接结果,左指针和右指针遇到字母时,交换各自位置上的字符,遇到其他字符正常拼接,直到相遇
/**
* @param {string} S
* @return {string}
*/
var reverseOnlyLetters = function(S) {
let left = 0,
right = S.length - 1;
let LS = "";
let RS = "";
const reg = /[a-zA-Z]/;
while (left < right) {
while (!reg.test(S[left]) && left < right) {
LS += S[left];
left++;
}
while (!reg.test(S[right]) && left < right) {
RS = `${S[right]}${RS}`;
right--;
}
if (left >= right) break;
LS += S[right];
RS = `${S[left]}${RS}`;
left++;
right--;
}
if (left === right) {
LS += S[left];
}
return `${LS}${RS}`;
};
也可以分割成数组,用双指针法交换数组上两个位置的字符然后拼接
/**
* @param {string} S
* @return {string}
*/
var reverseOnlyLetters = function(S) {
let left = 0,
right = S.length - 1;
const res=S.split("")
const reg = /[a-zA-Z]/;
while (left < right) {
while (!reg.test(S[left]) && left < right) {
left++;
}
while (!reg.test(S[right]) && left < right) {
right--;
}
if (left >= right) break;
[res[left],res[right]]=[res[right],res[left]]
left++;
right--;
}
return res.join("")
};
2.按奇偶排序数组
题目:
给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。
对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。
你可以返回任何满足上述条件的数组作为答案。
思路:还是双指针法,一个指针记录奇数位上的数字,一个记录偶数位上的数字,遇到偶数位上是奇数停,另一个一样,然后交换。
/**
* @param {number[]} A
* @return {number[]}
*/
var sortArrayByParityII = function(A) {
let a = 0,
b = 0;
while (a < A.length / 2) {
while (a < A.length / 2 && !(A[2 * a] % 2)) {
a++;
}
while (b < A.length / 2 && A[2 * b + 1] % 2) {
b++;
}
if (a >= A.length / 2 || b >= A.length / 2) break;
[A[2 * a], A[2 * b + 1]] = [A[2 * b + 1], A[2 * a]];
}
return A;
};
3.长按键入
题目:
你的朋友正在使用键盘输入他的名字 name。偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次。
你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),那么就返回 True。
思路:双指针各自指向两个字符串的开头,然后依次比较字符,遇到不同的字符,第二个指针往后遍历,直到移动到与当前字符不同的位置,这时如果还不同,则返回false。第一个字符串如果遍历结束,第二个字符串也要进行移动,直到移动到与当前字符不同的位置。这时比较第二个字符的位置,如果右侧仍有字符,则不符合条件
/**
* @param {string} name
* @param {string} typed
* @return {boolean}
*/
var isLongPressedName = function(name, typed) {
const l = name.length;
const lr = typed.length;
if (l > lr) return false;
let r = 0;
for (let i = 0; i < l; i++) {
if (name[i] !== typed[r]) {
while (typed[r] == typed[r - 1]) {
r++;
}
if (r >= lr) return false;
if (name[i] !== typed[r]) return false;
}
r++;
}
while (typed[r] == typed[r - 1]) {
r++;
}
return r >= lr;
};
4.独特的电子邮件地址
题目:
每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔。
例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名。
除了小写字母,这些电子邮件还可能包含 '.' 或 '+'。
如果在电子邮件地址的本地名称部分中的某些字符之间添加句点('.'),则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如,"alice.z@leetcode.com” 和 “alicez@leetcode.com” 会转发到同一电子邮件地址。 (请注意,此规则不适用于域名。)
如果在本地名称中添加加号('+'),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如 m.y+name@email.com 将转发到 my@email.com。 (同样,此规则不适用于域名。)
可以同时使用这两个规则。
给定电子邮件列表 emails,我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少?
思路:解析本地名称,遇到'@',则直接拼接后面的,遇到'+',忽略后面的,遇到'.'就跳过。注意这三个优先级是从高到低的。
然后用set记录
/**
* @param {string[]} emails
* @return {number}
*/
var numUniqueEmails = function(emails) {
const adress = new Set();
for (const n of emails) {
const l = n.length;
let s = "";
let flag = false;
for (let i = 0; i < l; i++) {
if (n[i] == "@") {
s += n.slice(i);
break;
} else if (!flag) {
if (n[i] == "+") {
flag = true;
} else if (n[i] !== ".") {
s += n[i];
}
}
}
adress.add(s);
}
return adress.size;
};
也可以分割字符串,先替换'.',然后用'+'分割
/**
* @param {string[]} emails
* @return {number}
*/
var numUniqueEmails = function(emails) {
return [...new Set(emails.map(item => {
let list = item.split('@')
list[0] = list[0].replace(/\./g,'').split('+')[0]
return list.join('@')
}))].length
};
5.最近的请求次数
写一个 RecentCounter 类来计算最近的请求。
它只有一个方法:ping(int t),其中 t 代表以毫秒为单位的某个时间。
返回从 3000 毫秒前到现在的 ping 数。
任何处于 [t - 3000, t] 时间范围之内的 ping 都将会被计算在内,包括当前(指 t 时刻)的 ping。
保证每次对 ping 的调用都使用比之前更大的 t 值。
思路:维护一个队列,每次Ping的时候,对小于t-3000的成员出列
var RecentCounter = function() {
this.list = [];
};
/**
* @param {number} t
* @return {number}
*/
RecentCounter.prototype.ping = function(t) {
this.list.push(t);
while(this.list[0]<t-3000){
this.list.shift()
}
return this.list.length
};
/**
* Your RecentCounter object will be instantiated and called as such:
* var obj = new RecentCounter()
* var param_1 = obj.ping(t)
*/