zoukankan      html  css  js  c++  java
  • LeetCode:180.连续出现的数字

    题目链接:https://leetcode-cn.com/problems/consecutive-numbers/

    题目

    编写一个 SQL 查询,查找所有至少连续出现三次的数字。

    +----+-----+
    | Id | Num |
    +----+-----+
    | 1 | 1 |
    | 2 | 1 |
    | 3 | 1 |
    | 4 | 2 |
    | 5 | 1 |
    | 6 | 2 |
    | 7 | 2 |
    +----+-----+
    例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。

    +-----------------+
    | ConsecutiveNums |
    +-----------------+
    | 1 |
    +-----------------+

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/consecutive-numbers
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解答

    先总结方法:

    1. 使用自连接,3个表连接;(如果连续出现1000次,这个方法就不行了。。)
    2. 使用 oracle 窗口函数;
    3. 使用 MySQL 变量的方式;

    一开始看的时候,毫无头绪。。

    解法一

    粗略的看了下解答,用自连接的方法,尝试了下,居然通过了。

    ---- oracle ----
    /* Write your PL/SQL query statement below */
    select distinct a.Num as ConsecutiveNums
    from Logs a,
         Logs b,
         Logs c
    where a.Id = b.Id + 1
    and a.Id = c.Id + 2
    and a.Num = b.Num
    and a.Num = c.Num --- 806ms
    

    考虑如果 id 不连续出现的情况,则需要在数据表中插入一列新的 id 自增数据进行标识。

    解法二

    1. 由于要获取至少连续3次出现的数字,看到这个题肯定是会变的,如果是至少连续出现4次(100次),连接4个表(连接1000个)?这种方法肯定是不可取的。

    2. 找规律,找出这连续起来的数字有什么规律呢?发现连续的数字是相同的数字,但是id有可能不是连续的,我们就需要通过对结果集进行再次编号,让其变成连续的。

    3. 首先我们获取到对每条数据编号从1开始使用 row_number() 函数使用 id 来排序。

    4. 然后我们通过另一种方式排序将这些 num 值一样的进行排序,然后对其编号同样使用 row_bumber() 使用 num 来分组使用 id 排序 over(partition by num order by id)

    5. 通过3、4步骤,两个相减之后我们可以得到,只要是相等的,则相减的值是一样的。而且如果不连续的话相减值也不一样。

    6. 最后再通过 numrn 两个共同分组找到一样的一共有几个,就可以找到连续的了。

    最终代码为:

    ---- oracle ----
    /* Write your PL/SQL query statement below */
    select distinct Num as ConsecutiveNums
    from 
    (
    	select Num,
    		   rn,
    		   count(Id) as cnt
    	from
    		(	   
    		select Id,
    			   Num,
    			   row_number() over(order by id) - row_number() over(partition by num order by id) as rn
    		from Logs
    		) 
    	group by Num, rn
    ) 
    where cnt >= 3; ---- 1414ms 好慢
    

    想了想,会不会存在 Num + rn 误判的情况?因为一直递增,貌似不会。

    解法三

    使用2个变量进行统计。

    ---- MySQL ----
    select distinct t.Num as ConsecutiveNums
    from
    (
    	select a.Num,
    		   @cnt := if(@pre = a.Num, @cnt + 1, 1) cnt,
    		   @pre := a.Num pre
    	from Logs a,
    		 (select @pre := null,
    				 @cnt := 0) b
    ) t
    where t.cnt >= 3; ---- 179ms
    

    判断当前Num与上一个Num是否一致,如果是cnt加一,如果不是,重新计数。

    高明!

    思考

    联想到以前自己的一个奇思妙想:赌钱!押大还是押小,买定离手!

    1. 买1块钱大,赢了的话,继续买;
    2. 输了的话,买2块钱大;
    3. 赢了的话,恢复买1块,输了的话,买4块钱大;
    4. 以此循环
    5. 设定上限,直到128块就认输,止损。

    当时想到这个做法的时候,问自己,如果我有较多的资金的话,假设我有1w,那一直买,买到8192的时候,已经是2的13次方了。。不可能连续输了13次吧。。当时这么想。。

    后来,觉得连续开13次小还是有概率的,想用程序随机模拟一下输赢的概率。。但是拖延症上身,一直没有去实践。。

    今天这道题,尝试一下吧。。

  • 相关阅读:
    请朋友做事,须以名誉为限,为朋友做事,亦须以名誉为限
    这世上总有一些人记得你,关注着你,牵挂着你
    杏花春雨已不再,牧童遥指已不再,剑门细雨渭城轻尘也都已不再
    如果要你做鲁滨逊,你会选第三型还是第二型的朋友做“礼拜五”呢
    人类最不能伤害的就是自尊
    单靠理论和教训是无济于事的
    交真朋友已是件比较奢侈的事儿
    他一定是一个懂生活、懂人生,爱自己、爱别人的人
    国子监,就是从前的大学
    只有把理想和现实有机结合起来,才有可能成为一个成功之人
  • 原文地址:https://www.cnblogs.com/hider/p/11763568.html
Copyright © 2011-2022 走看看