[算法]Java实现 不断前移重复出现的元素 Move Element To Front
来源:互联网 发布:windows mirai病毒 编辑:程序博客网 时间:2024/06/07 02:27
不断前移重复出现的元素 Move Element To Front
关键词
链表 Java 前移元素 删除
算法过程
- 使用链表存储数据,依次读取单个元素;
- 当前输入元素与先前输入的元素存在重复时,先删除链表中的结点;
- 于链表表头插入元素;
完整源码
/* JavaCode 重复元素前移*/// ---- 测试用例 ---- public class TestMove2Front{ public static void main(String args[]){ MoveToFront m; m = new MoveToFront(); int[] a = {4,3,2,2,1,2,0,1,2}; System.out.println("Push code \n" + "Top same: 0,First time: 1;Aagin: 2\n"); for(int i=0;i<a.length;i++){ int code = m.checkDup(a[i]); System.out.println("Input a[i]: "+a[i]+" ; Push code : "+code+"\n"); if(code>0) m.push(a[i],code); } while(!m.isEmpty()) System.out.println("Out: "+m.pop()); }}// ---- 实现类 ----class MoveToFront{ private Node first; private int N; // 循环类实现链表结构 public class Node{ int item; Node next; } // 判断链表是否为空 public boolean isEmpty(){ return first == null; } public MoveToFront(){ } // 弹出表头元素 public int pop(){ int item = first.item; first = first.next; return item; } // 表头插入元素 public void push(int item){ Node oldfirst = first; first = new Node(); first.item = item; first.next = oldfirst; } // 判断元素是否重复,返回状态代码 /* code :0 相同元素连续输入,即:当前输入元素与表头一致; code : 1 不存在重复元素,不进行结点删除操作; code : 2 存在重复元素,进行结点删除操作; */ public int checkDup(int item){ int code = 0; Node current = first; boolean again = false; int step = 0; //记录从表头开始计数达到重复结点需要走的步数 while(current!=null){ if(current.item == item){ again = true; // 值为真,说明存在重复结点 break; } current = current.next; step++; } if(!again) code = 1; else{ // 对重复结点进行删除 if(item == first.item) code = 0; //代表重复元素连续输入 else{ System.out.println("Duplicate step : "+step); //输入要前进的步数用于测试观察 current = first; for(int i=0;i<(step-1);i++)//找到要被删除的结点的前一结点 current = current.next; // 进行结点删除操作 current.next = current.next.next; code = 2; } } return code; }}
输出结果
Push code Top same: 0,First time: 1;Aagin: 2Input a[i]: 4 ; Push code : 1Input a[i]: 3 ; Push code : 1Input a[i]: 2 ; Push code : 1Input a[i]: 2 ; Push code : 0Input a[i]: 1 ; Push code : 1Duplicate step : 1Input a[i]: 2 ; Push code : 2Input a[i]: 0 ; Push code : 1Duplicate step : 2Input a[i]: 1 ; Push code : 2Duplicate step : 2Input a[i]: 2 ; Push code : 2Out: 2Out: 1Out: 0Out: 3Out: 4
代码心得
用例代码能做到以下3件事:
- 针对当前输入元素,判断是否存在重复元素,并返回对应的状态码
int checkDup(int item)
; - 针对返回的状态吗,选择要进行相关的链表操作
if(code>0){...}
; - 发送进行链表操作的指令
push(int item)
;
实现类,就是上述操作的具体实现,尽量做到了DO WAHT 以及HOW TO DO 的各司其职;
调试代码的过程中遭遇了两次 NullPointerException
1、计数
最初的实现类中,使用了一个int N
来记录结点数判断链表是否为空,删除重复结点时,忘记把计数减一了,导致用例代码中遍历到了一个NullPointerException。解决方案: 直接判断表头结点是否为NULL来判断链表是否为空;
public boolean isEmpty(){ return first == null; }
2、 删除
一开始完全顾着写存在重复的情况,没有先进行预判,结果在删除结点的时候,单单一句 current.next = current.next.next;
就会报空指针。
BUG比较曲折:后来开断点调试发现是因为在最初的糟糕设计里,那些不存在重复元素的情况下, 按照代码其实步数step会一直走到尾结点,那样的话尾结点的next已然是null了,怎么可以给null赋值,后来是把代码整体全部改了之后,也就是先预判了存在重复的情况才可以进行删除操作;
下面这段历史代码还是很有趣的,因为我觉得它其实看上去根本就是废话,但是在不进行预判的时候(也就是不判断是不是存在重复的时候,奇迹般地起效了…)要对链表进行删除操作真的要非常小心,删头删尾删中间都不一样:
if(current.next != null){ current.next = current.next.next; } else{ current.next = null; }
应用即最常用的数值永远位于前部
0 0
- [算法]Java实现 不断前移重复出现的元素 Move Element To Front
- Move-to-front transform 算法
- codeforces gym 100342F Move to Front
- 【LeetCode-面试算法经典-Java实现】【027-Remove Element(删除数组中指定的元素)】
- Java实现单链表(已排序)去重(保留重复元素第一次出现的节点)
- 去掉数组中重复出现元素的算法
- Java实现-带重复元素的子集
- Java实现-带有重复元素的排列
- Remove Element--原地移除重复元素
- 【程序员面试宝典】有1千万条短信,找出重复出现最多的前10条 算法实现
- C++实现的位图法去除重复出现的元素
- java算法之简单的移除数组中的指定元素Remove Element
- Java实现二分查找算法(元素可重复)
- java统计List中的元素重复出现的次数
- 解析、查找数组中重复出现的元素(Java)
- Codeforces Gym 100342F Move to Front 平衡树
- 求最大流的Relabel-to-Front算法
- ArrayList实现的删除重复元素的算法
- B\S备忘录16——tomcat压缩版安装
- Linux下套接字详解(一)----TCP/UDP的区别与联系
- 使用CNN(convolutional neural nets)检测脸部关键点教程(二):浅层网络训练和测试
- CLang之简单介绍
- 疯狂Java学习笔记(56)------------对象序列化
- [算法]Java实现 不断前移重复出现的元素 Move Element To Front
- LBSN中好友与用户活动的关系
- 跟我学Java反射——一步曲
- itop4412的linux环境搭建
- change between std::string & int demo
- 第十三周阅读项目(虚析构函数)
- Mongodb启动配置
- Codeforces Round #305 B题 思维+贪心
- 点类派生直线类