[路飞]请求最近次数,第k个数,亲密字符串

119 阅读4分钟

**一.#### 最近的请求次数

写一个 RecentCounter 类来计算特定时间范围内最近的请求。**

请你实现 RecentCounter 类:

RecentCounter() 初始化计数器,请求数为 0 。 int ping(int t) 在时间 t 添加一个新请求,其中 t 表示以毫秒为单位的某个时间,并返回过去 3000 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在 [t-3000, t] 内发生的请求数。 保证 每次对 ping 的调用都使用比之前更大的 t 值。

 

示例 1:

输入: ["RecentCounter", "ping", "ping", "ping", "ping"] [[], [1], [100], [3001], [3002]] 输出: [null, 1, 2, 3, 3]

解释: RecentCounter recentCounter = new RecentCounter(); recentCounter.ping(1); // requests = [1],范围是 [-2999,1],返回 1 recentCounter.ping(100); // requests = [1, 100],范围是 [-2900,100],返回 2 recentCounter.ping(3001); // requests = [1, 100, 3001],范围是 [1,3001],返回 3 recentCounter.ping(3002); // requests = [1, 100, 3001, 3002],范围是 [2,3002],返回 3

解题思路:本题可以用数组来解决,请求一次就将当前时间存储在数组中,然后循环数组,从数组第一个开始逐个与当前时间作对比,判断是否超出3000秒,超出就的就删掉,代码实现如下:

var RecentCounter = function() {
    //定义一个空数组用来保存时间
    this.arr = []
};
RecentCounter.prototype.ping = function(t) {
    //将求亲时间保存在数组里
    this.arr.push(t);
    循环数组,判断是否超过3000秒,超过就数组头删除调,
    while(t - this.arr[0] > 3000) {
        //删除数组头节点
        this.arr.shift();
    }
    //数组剩下的长度就是3000秒内的数据了
    return this.arr.length;
};

二.第k个数

有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。

示例 1:

输入: k = 5

输出: 9

解题思路:这个一个特殊的数组由3 5 7的倍数有小到大排列的数组,要在这个特殊的数组里取出低k位数.所以先将k之前的数组找出来就可以获得第k位数了

var getKthMagicNumber = function(k) {
    //定义一个数组,默认第一位是1,
    let arr = [1];
    //3的倍数变量
    let p3 =  arr[0]*3;//保存3的倍数
    let p5 = arr[0]*5;//保存5的倍数
    let p7 = arr[0]*7;//保存7的倍数
    //获得最小值
    let min = p3 < p5 ? p3 : p5;
    min = min < p7 ? min : p7;
    //将最小值插入数组
    arr.push(min);
    //记录k为数字
    let kk = k;
    //记录3的倍数的索引
    let i3 = 0;
    //记录5的倍数的索引
    let i5 = 0;
    //记录7的倍数索引
    let i7 = 0;
    //辨别k位数字
    while(k --){
       //如果最小值是3的倍数就将3的索引加一,获得新的倍数
       if(min == p3){
            i3 ++;
            p3 = arr[i3] * 3;
        }
        //如果最小值是5的倍数就将5的索引加一,获得新的倍数
        if(min == p5){
            i5 ++;
            p5 = arr[i5] * 5;
        }
        //如果最小值是7的倍数就将7的索引加一,获得新的倍数
        if(min == p7){
            i7 ++;
            p7 = arr[i7] * 7;
        }
        //从新获得最小值
        min = p3 < p5 ? p3 : p5;
        min = min < p7 ? min : p7;
        将最小值插入数组
        arr.push(min);
    }
    返回k位数
    return arr[kk-1]
};

亲密字符串

给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。

交换字母的定义是:取两个下标 i 和 j (下标从 0 开始)且满足 i != j ,接着交换 s[i] 和 s[j] 处的字符。

例如,在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad" 。  

示例 1:

输入:s = "ab", goal = "ba" 输出:true 解释:你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 相等。 示例 2:

输入:s = "ab", goal = "ab" 输出:false 解释:你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba",此时 s 和 goal 不相等。

思路:两个数组只要任意两个数组交换相等就是亲密字符串,所以 aabc 和 aabc 也是亲密字符串,本题有两种可能: 一.是如果两个数组相等,就需要判断数组数组里是有有相等的字符串,如果有就是亲密字符串,如果没有就不是,
二是加入第一个数组arr的k位为不同的字符串,m第二个不相等的字符串,如果第二个数组arr2的ar2[m] == arr[k],arr2[k] == arr[m],且需要除了两个不同字符串以外,其他相同位置的字符串都要相等,那么这两个数组也是亲密字符串,代码如下:

var buddyStrings = function(s, goal) {
    //如果两个数组长度不相等肯定就不是亲密字符串
    if(s.length != goal.length) return false;
    //两个数组相等,判断是否有重复字符串,有的话就是亲密字符串,没有就不是
    if(s === goal) return has_repeate(s);
    //定义i 为第一个不同字符串位置,j为第二个不相同字符串位置
    let i=0,j;
    //找第一个不相同的位置
    while(s[i] === goal[i]) i ++;
    //i第一个 不相等的位置
    j = i +1;
    //找第二个不相同字符串位置
    while(j < s.length && s[j] === goal[j]) j ++;
    //如果j等于数组长度就表示没有第二个不相同字符串
    if(j === s.length) return false;
    //判断交叉字符串是否相等,相等就是亲密字符串
    if(s[i] !== goal[j] || s[j] !== goal[i]) return false;
    //j是第二个不相等的位置,判断第二个不相等的后面是否相等,所以需要加一
    j = j + 1;
    //判断第二相同字符串是否相等,相等就是亲密字符串,否则就不是
    while(j < s.length && s[j] === goal[j]) j ++;
    //只有j等于数组长度就表示后半截是相同的
    if(j !== s.length) return false;
    return true;
     
};
var has_repeate = function(str){
    let len = str.length
    for(let i = 0; i < len; i ++){
        for(let j = i+1; j < len - i;j ++){
            if(str[i] === str[j]) return true
        }
    }
    return false;
}