算法-一个经典sql 题和一个Java算法题
1.sql题描述
话说有一个日志表,只有两列,分别是连续id和num 至于啥意思,把它当金额把。现在想知道连续次数3次及以上的num,数据如下
id | num |
---|---|
1 | 1 |
2 | 1 |
3 | 1 |
4 | 2 |
5 | 3 |
6 | 4 |
7 | 4 |
8 | 4 |
那么结果只有1,4满足条件,问这个sql该怎么写?
2.思路和解法
分析:题目简单,没有歧义,能看得懂,像连续几次的这种问题一定是用到窗口函数,首先想到的是排名row_number
然后lag
怎么体现连续呢,肯定是需要用到一个排序的id,由于题目给了id是连续递增的,可以省去row_number了
所以第一步,上lag,结果就是如下:
id | num | lagid |
---|---|---|
1 | 1 | null |
2 | 1 | 0 |
3 | 1 | 0 |
4 | 2 | 1 |
5 | 3 | 1 |
6 | 4 | 1 |
7 | 4 | 0 |
8 | 4 | 0 |
得到lagid后,连续怎么用呢,首先只有为0的才满足条件,所以可以做一个筛选,结果就如下表去掉xxx
的,下面观察0的行,怎么区分3 行的 0 和 7行的 0呢,想到使用新分组,rid 这样就把lagid 相同,num相同的排序,最后再加一列,id-rid 相同的分为一组
id | num | lagid | rid | gid |
---|---|---|---|---|
1 | 1 | null xxx | ||
2 | 1 | 0 | 1 | 1 |
3 | 1 | 0 | 2 | 1 |
4 | 2 | 1 xxx | ||
5 | 3 | 1 xxx | ||
6 | 4 | 1 xxx | ||
7 | 4 | 0 | 1 | 6 |
8 | 4 | 0 | 2 | 6 |
-- 完整sql ## 解法1 SELECT num FROM (SELECT id, num, lagid, (id-row_number() over(PARTITION BY num, lagid ORDER BY id)) AS gid FROM (SELECT id, num, num- lag(num) (OVER PARTITION BY 1 ORDER BY id) AS lagid) tmp1 WHERE lagid=0 ) tmp2 GROUP BY num, gid HAVING count(*) >= 2 ## 解法2 select num, gid, count(1) as c from ( select id, num, id-row_number() over(PARTITION BY num ORDER BY id) as gid from (select * from logs order by num,id) a ) b group by num,gid
后面想到了更好的,其实不用lag
,也不用order by
全局排序,id 的作用和日期一样,一般是用来配合row_number
来解决连续问题的,所以row_number
必不可少,那么可以这样写(神他妈简单是不是,别想复杂了):
SELECT num, gid FROM (SELECT num, id-row_number() OVER (PARTITION BY num ORDER BY id) gid FROM logs) GROUP BY num, gid HAVING count(1) >= 3
3. Java题描述
首先,给你一个初始数组 arr。然后,每天你都要根据前一天的数组生成一个新的数组。第 i 天所生成的数组,是由你对第 i-1 天的数组进行如下操作所得的:假如一个元素小于它的左右邻居,那么该元素自增 1。假如一个元素大于它的左右邻居,那么该元素自减 1。
首、尾元素 永不 改变。
过些时日,你会发现数组将会不再发生变化,请返回最终所得到的数组。
示例 1:
输入:[6,2,3,4]
输出:[6,3,3,4]
解释:
第一天,数组从 [6,2,3,4] 变为 [6,3,3,4]。
无法再对该数组进行更多操作。
示例 2:
输入:[1,6,3,4,3,5]
输出:[1,4,4,4,4,5]
解释:
第一天,数组从 [1,6,3,4,3,5] 变为 [1,5,4,3,4,5]。
第二天,数组从 [1,5,4,3,4,5] 变为 [1,4,4,4,4,5]。
无法再对该数组进行更多操作。
3.3 分析和解法
-
首先考虑一轮遍历怎么写,应该很简单把,思路就是一个大小为3的窗口
-
用一个flag来标志每一轮是否有改过数据。那么代码如下:
public int[] get(int[] input) { if (input == null || input.length <=2) return input; boolean flag = false; do { flag = false; for (int i=1;i+1 < input.length;i++){ if (input[i] < input[i+1] && input[i] < input[i-1] ) { input[i] +=1; if (!flag) flag = true; } if (input[i] > input[i+1] && input[i] > input[i-1] ) { input[i] -=1; if (!flag) flag = true; } } } while(flag) return input; }
大数据开发,更多关注查看个人资料

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
面试官:说说你对【注解】的理解
本文主要内容如下: 背景 现在已经处于注解盛行时代,注解@Override ,这个注解是再熟悉不过了,还有@Controller、@RequestMapping、@Service..... 注解已经是作为一个开发中必备的技能了。 如果在面试中被问到注解,说不出个123,就只能回去等通知了。 什么是注解? 注解annotation是JavaSE5.0中新增功能。可以理解为注解是一种标记,这种标记可以在编译、类加载、运行时被读取,并执行相应的处理。 它可以添加到程序的任何元素上:包声明、类型声明、构造方法、普通方法、成员变量、参数。 注解的老大: package java.lang.annotation; //是个接口 public interface Annotation { boolean equals(Object obj); int hashCode(); String toString(); //获取注解类型 Class<? extends Annotation> annotationType(); } JDK自带为我们提供了元注解,下面就来...
- 下一篇
使用Nginx做页面采集, Kafka收集到对应Topic
0.架构简介 模拟线上的实时流,比如用户的操作日志,采集到数据后,进行处理,暂时只考虑数据的采集,使用Html+Jquery+Nginx+Ngx_kafka_module+Kafka来实现,其中Ngx_kafka_module 是开源的专门用来对接Nginx和Kafka的一个组件。 1.需求描述 1.1 用html和jquery 模拟用户请求日志 其中包括下面下面几项: 用户id:user_id, 访问时间:act_time, 操作: (action,包括click,job_collect,cv_send,cv_upload) 企业编码job_code 1.2 用Nginx接受1.1中的请求 1.3 接受完请求后,使用ngx_kafka_module将数据发送到Kafka的主题tp_individual 中。 1.4 在kafka中使用一个消费者消费该主题,观察 2.搭建步骤 2.1 Kafka安装 由于使用现成的已安装好的docker-kafka镜像,所以直接启动即可. 2.2 安装Nginx,并启动 $ cd /usr/local/src $ git clone git@githu...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS关闭SELinux安全模块
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker使用Oracle官方镜像安装(12C,18C,19C)