之前一直刷leetcode,做了这么多算法提,总觉得没什么用武之地,不知道大家有没有这样的情况,刷了这么多算法,却实际在工作中的应用的很少。 然后这两天看到有个需求,不算难,在leetcode应该也就是简单级别,终于有个实际的问题来练练手了,开心
先来看问题是什么
如下图,服务器获取到一个列表,这个列表中的数据类型有两种UI显示方式,一种是小的方块,一行可以放5个,另一种是大方块,一行只能放一个,现在呢,服务器返回的顺序是未知的,但需要整个列表除了最后不能有空的间隙,如图:
一开始想的是使用双指针,一个指向小方块,一个指向大方块,然后遇到第一列就判断,是否需要插入大方块,否则插入小方块,但遇到了几个问题:
- 什么时候插入大方块,小方块补完空隙后,怎么知道要不要插入大方块
- 当前界面的第一列位置并不是数组位置取5的余数,因为大方块一个就占了一行
- 当遇到连续的大方块,小方块怎么去跨越几个大方块去补位
想了一下没什么思路,那就换个方向吧
如果我用一个变量 a 去存大方块对象,当遇到空隙先存起来,然后等到时机合适再把这个大方块插入进去,是不是逻辑清晰一点
i 是数组位置
bigNum 是已添加的大方块数量
此时的界面 pos = ( i - (a != null?1:0) + bigNum ) % 5
然后对pos%5取余,余数为0就判断a是否空,不为空的话就插入,**bigNum++ ,**为空就继续看下一个是否是大方块
这样解决了1,2问题,但还有一个问题3没解决,,连续大方块怎么处理,聪明的小伙伴应该已经想到了,把a对象换成队列就可以了,队列先进先出的特性非常符合我们的需求,当遇到大方块不能插入的时候,存入队列,等合适时机出队列,然后在遍历完一遍以后,把队列剩下的大方块插入到列表末尾就可以了
伪代码:
List<Data> sort(List<Data> originList) {
List<Data> resultList = new ArrayList<>();
Queue<Data> bigQueue = new ArrayDeque<>();
int bigNum = 0;
for (int i = 0; i < originList.size(); i++) {
Data cur = originList.get(i);
if ((resultList.size() - bigQueue.size()) % 5 == 0 ) {
while(bigQueue.size() > 0){
resultList.add(bigQueue.poll());
bigNum++;
}
}
if (cur.isBig) {
resultList.add(cur);
} else {
if ((resultList.size() - bigNum) % 5 == 0) {
resultList.add(cur);
bigNum++;
} else {
bigQueue.add(cur);
}
}
}
resultList.addAll(bigQueue);
return resultList;
}