题目:
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
Java实现代码:
一:利用递归
public ListNode deleteDuplication(ListNode pHead){
if (pHead == null || pHead.next == null) {//若链表为空或者链表只有一个节点
return pHead; //返回该节点
}
if (pHead.val == pHead.next.val){ //说明此项与下一项是重复元素
ListNode pNode = pHead.next; //将指针指向第二个重复的元素(当前项的下一项)
//pNode为当前重复的的第一个元素 若该值等于第一个值 一直向下找到都重复的值
while (pNode != null && pNode.val == pHead.val) {
pNode = pNode.next;
}
return deleteDuplication(pNode); //从第一个不相同的值开始递归删除操作
} else { //此项和下一项不是相同元素
pHead.next = deleteDuplication(pHead.next); //从该项的下一项开始向后递归删除重复元素
return pHead;
}
}
二:非递归操作
public static ListNode deleteDuplication1(ListNode pHead){
ListNode dummyNode = new ListNode(-1); //设置虚拟头结点
dummyNode.next = pHead;
ListNode cur = pHead; //当前节点
ListNode lastNode = dummyNode;
if (cur == null || cur.next == null) {
return cur;
}
while (cur != null && cur.next != null) {
if (cur.val == cur.next.val) { //如果当前节点和下一节点为相同节点
int val = cur.val; //将当前节点的值保存起来
while (cur != null && cur.val == val) { //向下一直找到相同的节点
cur = cur.next;
}
lastNode.next = cur;
} else { //没有重复元素
lastNode = cur;
cur = cur.next;
}
}
return dummyNode.next;
}
测试:
对链表节点的声明进行改动
public class ListNode {
//单向链表
int val; //节点的值
ListNode next = null; //节点的指向
ListNode(int val) {
this.val = val;
}
//也可以自定义一个构造函数 通过数组转成链表,当前ListNode为头结点
ListNode(int[] arr) {
if (arr == null || arr.length == 0) {
throw new IllegalArgumentException("数组为空");
}
this.val = arr[0]; //当前的节点为数组的第一个元素
ListNode cur = this; //cur初始化为当前节点
for (int i = 1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
ListNode cur = this;
while (cur != null) {
sb.append(cur.val + "->");
cur = cur.next;
}
sb.append("NULL");
return sb.toString();
}
}
主方法:
public static void main(String[] args){
int[] arr = {1,2,3,3,4,4,5};
System.out.println(deleteDuplication(new ListNode(arr)));
}