2024/1/26总结

本文介绍了如何在给定数组中移除所有等于特定值的元素,同时保持O(1)额外空间。提供了两种方法:暴力解法逐个判断和双指针法,后者通过合并遍历来提高效率。

一、移除元素

题目:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

注意:这里的移除并不是“删除”,而是“覆盖”。(数组中的的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖)

解法一:暴力解法(逐个判断) 【就是从头开始,找到目标元素val,就执行一次任意位置删除】
#include<assert.h>
void Erase(int* nums, int pos, int length)
{
    assert(length > 0);   
    while (pos < length - 1)
    {
        nums[pos] = nums[pos + 1];  
        pos++;  
}

int removeElement(int* nums, int numsSize, int val)
{
    assert(nums);  
    int i = 0;
    int length = numsSize;
    for (i = 0; i < numsSize; i++)
    {
        if (nums[i] == val)
        {
            Erase(nums, i, numsSize--);
            i--;    
            length--;  
        }
    }

    return length; 
}
解法二:双指针法  【通过一个快指针和慢指针在一个for循环下完成两个for循环的工作

快指针和慢指针的初始位置一致。遍历整个数组,两个指针所指向的值进行比较。

int removeElement(int* nums, int numsSize, int val)
{
    int slow = 0;
    for(int fast = 0; fast < numsSize; fast++) 
    {
  
        if(nums[fast] != val) 
        {
            nums[slow++] = nums[fast];
        }
    }
    return slow;
}

总结:本题的解法还有很多,本人对本题的理解有待提高,大家多指点!

dates_test y_test pred_test 2024/9/3 88.33333333 112.5269743 2024/9/3 88.33333333 87.66773838 2024/9/8 108.1818182 101.305023 2024/9/9 115.4545455 95.94628989 2024/9/13 44 50.22694321 2024/9/18 80 83.50581792 2024/9/28 75 72.03481818 2024/9/29 100 70.63235275 2024/10/2 74.16666667 60.0974857 2024/10/5 102.7272727 93.70316775 2024/10/11 130.9090909 90.89599003 2024/10/11 130.9090909 106.1278653 2024/10/13 63.75 70.22797207 2024/10/15 86.66666667 84.94518368 2024/10/16 71.66666667 67.6315823 2024/10/17 35.5 41.12031575 2024/10/22 37.5 41.03879175 2024/10/24 75.83333333 75.25111555 2024/10/26 56.66666667 59.38398062 2024/10/27 67.5 77.832346 2024/10/30 78.33333333 74.74345001 2024/11/1 71.66666667 74.42641864 2024/11/1 71.66666667 79.26579196 2024/11/3 107.5 95.54370557 2024/11/5 55 88.56740098 2024/11/5 55 63.31681544 2024/11/7 70.83333333 69.54550807 2024/11/8 52.5 70.67583166 2024/11/9 50.5 65.56271868 2024/11/11 61.66666667 67.35173834 2024/11/13 66.66666667 67.28262989 2024/11/14 69.16666667 74.95588283 2024/11/16 62.5 67.71457132 2024/11/20 31.25 39.891552 2024/11/21 56.25 53.22487241 2024/11/21 56.25 45.76253479 2024/11/22 67.5 55.73400985 2024/11/22 67.5 71.83695125 2024/11/29 60 63.5601233 2024/12/3 121.25 123.4305079 2024/12/3 121.25 85.3482925 2024/12/4 78.75 118.7901925 2024/12/5 48.57142857 76.99301816 2024/12/5 48.57142857 56.97048272 2024/12/6 50 55.87833305 2024/12/9 63.75 76.94141229 2024/12/11 90 91.33542966 2024/12/11 90 86.81876617 2024/12/12 105 88.86386619 2024/12/12 105 83.2873992 2024/12/28 44 52.28276036 2024/12/29 73.75 71.47314109 2024/12/31 145 113.5592608 2025/1/2 174.2857143 155.6452639 2025/1/3 204 167.5981065 2025/1/4 157.1428571 132.7838937 2025/1/5 75 92.49745297 2025/1/6 77.5 91.45886457 2025/1/10 44.28571429 54.07822402 2025/1/10 44.28571429 49.77849383 2025/1/11 78.75 78.33945264 2025/1/12 81.25 73.83615932 2025/1/13 106.25 80.49762555 2025/1/20 151.4285714 135.5365602 2025/1/21 133.75 129.3701745 2025/1/22 135 129.7498376 2025/1/24 91.25 146.2574101 2025/1/27 55 71.19681257 2025/1/28 62.5 66.08731135 2025/2/1 67.5 70.55055278 2025/2/2 58.75 66.17282227 2025/2/5 58.75 88.25618868 2025/2/8 39 77.09680956 2025/2/9 45.71428571 52.59000634 2025/2/15 86.25 82.55732834 2025/2/16 82.5 80.47600523 2025/2/19 63.75 77.20241091 2025/2/23 116.25 86.20812499 2025/2/24 120 99.71647402 2025/2/28 76.25 62.48392691 2025/3/3 28 49.58835197 2025/3/4 42.85714286 31.03968392 2025/3/5 48.57142857 57.86928852 2025/3/6 72.5 63.13378784 2025/3/7 80 78.53474335 2025/3/9 80 74.8908945 2025/3/9 80 86.4381764 2025/3/11 65 68.92648547 2025/3/15 42.5 47.87104828 2025/3/17 54.16666667 55.10420056 2025/3/19 70 71.56898471 2025/3/21 75.83333333 77.01770667 2025/3/24 70 74.56893424 2025/3/29 70 76.79240723 2025/4/1 71 80.49636367 2025/4/2 81.66666667 81.90300111 2025/4/5 84.16666667 78.87172554 2025/4/6 97.5 94.27099108 2025/4/7 84.16666667 89.69045916 2025/4/14 98 95.76669915 2025/4/21 42 110.7547733 2025/4/23 81.66666667 57.57965373 2025/4/24 61.5 83.89232336 2025/4/26 91.66666667 84.27197067 2025/4/27 58.33333333 63.2359425 2025/4/28 95 60.21913102 2025/4/30 68.33333333 73.17850563 2025/5/1 80.83333333 82.36145101 2025/5/2 86.66666667 83.28253032 2025/5/3 80.83333333 86.81863008 2025/5/4 103.6363636 98.15885845 2025/5/7 135.5 95.10256211 2025/5/7 135.5 116.0233971 2025/5/10 50 56.54042179 2025/5/15 50.83333333 56.13208029 2025/5/19 80 80.8703101 2025/5/21 55.83333333 57.59769333 2025/5/22 38.5 42.78308838 2025/5/22 38.5 63.21934594 2025/5/24 80.83333333 73.79815518 2025/5/25 123.6363636 79.32403802 2025/5/27 97.5 105.5559785 2025/5/28 64.16666667 69.09375382 2025/5/31 33.5 70.82817578 2025/5/31 33.5 34.23426147 2025/6/1 43 37.87608647 2025/6/11 65.83333333 40.92472477 2025/6/14 44.5 71.85373194 2025/6/15 67.5 47.3552771 2025/6/16 80.83333333 76.67770933 2025/6/18 40.5 56.99440466 2025/6/21 52.5 50.26688877 2025/6/24 67.5 70.07672005 2025/6/25 85.83333333 83.64304008 2025/6/26 48 47.23009884 2025/6/26 48 82.14277947 2025/6/27 27.5 32.65747275 2025/6/29 33 38.08214866 2025/7/2 40.5 41.67411208 2025/7/3 41.5 41.41264814 2025/7/4 62.5 42.44601331 2025/7/6 89.16666667 68.117607 2025/7/10 48 50.34278214 2025/7/12 38.5 54.11489636 2025/7/13 61.66666667 68.58124235 2025/7/14 57.5 74.65653795 2025/7/15 63.33333333 61.39286753 2025/7/16 61.66666667 61.32914242 2025/7/18 89.16666667 84.7154233 2025/7/19 109.0909091 85.33932655 2025/7/21 44.5 50.99408325 2025/7/23 47 67.89049979 2025/7/24 70.83333333 72.41964472 2025/7/24 70.83333333 65.9840856 2025/7/28 41.5 44.27687112 2025/7/31 68.33333333 67.99134975 2025/8/1 58.33333333 57.32271191 2025/8/2 66.66666667 72.74851308 2025/8/2 66.66666667 59.6210798 2025/8/3 85 83.60732756 2025/8/3 85 78.78748701 2025/8/8 48 60.12853279 2025/8/17 67.5 46.09111409 2025/8/18 55 71.52011334 2025/8/21 43.5 42.50301084 2025/8/26 95 96.08207568 2025/8/27 80 95.63145426 2025/8/28 85 71.81423784 2025/9/1 60 47.52937251 2025/9/3 74.16666667 68.18375631 2025/9/4 68.33333333 70.05693039 2025/9/5 73.33333333 70.05693039 2025/9/5 73.33333333 71.04672543 2025/9/21 32 35.85595145 2025/9/23 29.5 48.00505558 2025/9/25 25.5 33.71126822 2025/9/25 25.5 35.91251939 2025/9/29 32.5 37.6947908 观察以上预测结果,按照月、天对结果进行分析总结,
11-27
<think>好的,我现在需要解决用户的问题,即如何用SQL查询连续登录三天的用户记录。首先,我需要回忆一下相关的SQL知识,尤其是处理连续登录这类问题的方法。根据用户提供的引用内容,有三种不同的方法,我需要逐一分析,看看哪种更适合,或者是否能结合使用。 首先,用户引用了三种不同的方法。第一种是使用临时变量来计算连续登录次数,第二种是使用窗口函数ROW_NUMBER和日期差值,第三种可能也是类似的窗口函数方法。我需要先理解这三种方法的原理,然后比较它们的优缺点,再给出步骤化的解决方案。 第一个引用中的方法,使用临时变量@prev_time和@login_count。这种方法通过遍历登录记录,比较当前记录的上次登录时间,如果相差一天,则增加计数器,否则重置。然后通过分组找出最大连续登录次数是否达到3。这种方法可能在MySQL中有效,但使用用户变量需要注意顺序问题,尤其是在新版本的MySQL中,可能需要更谨慎的处理。 第二个引用使用ROW_NUMBER窗口函数,按用户分区并按日期排序,生成行号rn。然后用登录日期减去rn的天数,如果连续登录的话,这个差值会相同。例如,连续三天的日期减去对应的行号(1、2、3)会得到同一个日期。然后根据这个sub_date进行分组统计,找到次数大于等于3的情况。这种方法利用了窗口函数,逻辑比较清晰,但需要MySQL版本支持窗口函数(MySQL 8.0+)。 第三个引用中的示例数据展示了一个具体的问题,用户可能有重复日期或者间隔的情况,需要排除非连续的记录。例如,用户12024-04-30和2024-05-01之间有一天间隔,不算连续三天。但用户1有从04-25到04-28连续四天的登录,所以会被选中。 现在,我需要综合这些信息,给出一个适合的解决方案。可能需要分步骤讲解两种方法:使用窗口函数和使用临时变量。同时,要注意MySQL版本的支持情况,窗口函数方法适用于较新的版本,而临时变量方法可能在旧版本中更适用。 另外,用户的问题可能需要返回用户ID以及满足条件的记录,或者只是用户列表。需要明确需求,但根据引用中的示例,可能是要查询用户ID,并且统计他们是否有至少连续三天登录的记录。 接下来,我需要考虑如何编写这两种方法的SQL语句,并解释每一步的作用。例如,在窗口函数方法中,首先为每个用户的登录记录按日期排序并生成行号,然后计算日期与行号的差值,如果连续,这个差值相同。接着按用户和这个差值分组,统计每组的记录数,筛选出记录数≥3的情况。 对于临时变量方法,需要注意变量的初始化,以及在查询中的正确使用顺序。可能需要使用子查询来处理变量赋值,并按用户和日期排序,逐条检查是否连续。 此外,需要处理可能的重复日期,例如用户在同一天多次登录的情况,这时候应该去重,只保留唯一的日期。否则,重复的日期会影响连续性的判断。 最后,可能需要提供两种方法的优缺点比较,让用户根据自己的数据库版本和需求选择合适的方法。例如,窗口函数方法更现代且逻辑清晰,但需要MySQL 8.0+;而临时变量方法可能在旧版本中有效,但需要注意变量赋值的顺序和潜在的执行计划问题。 在测试过程中,可能需要构造测试数据来验证这两种方法的正确性。例如,用户1有连续四天登录的记录,用户2有三天连续,用户3有间断的记录,确保查询结果正确返回符合条件的用户。 总结来说,解决方案应包括两种方法的具体步骤、示例代码、以及注意事项,帮助用户理解如何实现查询连续三天登录的用户记录。</think>### 逐步解答:使用SQL查询连续登录三天的用户记录 #### 方法一:窗口函数法(适用于MySQL 8.0+) **步骤说明:** 1. **去重处理**:确保每天只保留一条登录记录。 2. **生成行号**:按用户分组并按登录日期排序,生成行号$rn$。 3. **计算日期差值**:将登录日期减去行号对应的天数,若连续登录则差值相同。 4. **分组统计**:按用户和差值分组,统计连续登录天数。 5. **筛选结果**:保留连续天数≥3的用户。 **示例SQL:** ```sql SELECT user_id FROM ( SELECT user_id, DATE_SUB(d, INTERVAL rn DAY) AS sub_date FROM ( SELECT user_id, DATE(login_time) AS d, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY DATE(login_time)) AS rn FROM login_tb GROUP BY user_id, DATE(login_time) -- 去重处理 ) t1 ) t2 GROUP BY user_id, sub_date HAVING COUNT(*) >= 3; ``` **公式解释:** - 连续登录时,日期序列$\{d_1, d_2, d_3\}$满足$d_2 = d_1 + 1$, $d_3 = d_2 + 1$。 - 若行号$rn$从1开始递增,则$d - rn$会得到固定值,例如: $$d_1 - 1 = d_2 - 2 = d_3 - 3 = \text{固定日期}$$ **优点**:逻辑清晰,兼容性较好(MySQL 8.0+)[^2]。 --- #### 方法二:临时变量法(兼容旧版MySQL) **步骤说明:** 1. **初始化变量**:设置临时变量存储上次登录时间和连续计数。 2. **遍历记录**:按用户分组并按日期排序,逐行判断是否连续。 3. **更新计数**:若日期差为1天则计数+1,否则重置为1。 4. **筛选最大值**:取每个用户的最大连续天数,筛选≥3的记录。 **示例SQL:** ```sql SELECT user_id FROM ( SELECT user_id, @login_count := IF(DATEDIFF(time, @prev_time) = 1, @login_count + 1, 1) AS login_count, @prev_time := time FROM login_tb, (SELECT @prev_time := NULL, @login_count := 0) vars WHERE user_id IN (SELECT user_id FROM register_tb) -- 可选:筛选已注册用户 ORDER BY user_id, time ) t WHERE login_count >= 3 GROUP BY user_id; ``` **公式解释:** - 连续登录条件:当前日期$d_n$与前一日期$d_{n-1}$满足: $$d_n - d_{n-1} = 1 \quad \Rightarrow \quad \text{计数+1}$$ - 最终筛选条件: $$\max(\text{login_count}) \geq 3$$ **优点**:兼容低版本MySQL,但需注意变量初始化顺序[^1]。 --- #### 两种方法对比 | 特性 | 窗口函数法 | 临时变量法 | |---------------------|-------------------------|---------------------------| | 兼容性 | MySQL 8.0+ | 所有MySQL版本 | | 执行效率 | 高(优化器自动处理) | 中(依赖排序和变量赋值) | | 代码可读性 | 高 | 中 | | 处理重复日期 | 自动去重 | 需手动去重 | --- #### 应用场景示例 假设表`login_tb`包含以下数据: | user_id | login_time | |---------|-------------| | 1 | 2024-04-25 | | 1 | 2024-04-26 | | 1 | 2024-04-27 | | 2 | 2024-05-01 | | 2 | 2024-05-02 | | 2 | 2024-05-03 | **输出结果:** ``` user_id 1 2 ``` --- ### 相关问题 1. **如何处理用户在同一天多次登录的情况?** 答:在子查询中使用`GROUP BY user_id, DATE(login_time)`去重[^2]。 2. **如何查询连续N天的登录用户(如7天)?** 答:将`HAVING COUNT(*) >= 3`中的3改为目标天数即可。 3. **如何优化大数据量下的查询性能?** 答:为`user_id`和`login_time`字段添加索引,减少全表扫描[^3]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值