版权声明:本文为博主NJU_ChopinXBP原创文章,发表于CSDN,仅供交流学习使用,转载请私信或评论联系,未经博主允许不得转载。感谢您的评论与点赞。 https://blog.csdn.net/qq_20304723/article/details/87888403
2019.2.23 《剑指Offer》从零单刷个人笔记整理(66题全)目录传送门
这道题也很简单,哈希表可以搞定大部分重复问题。如果不用哈希表的话,考虑到链表是排序的,因此重复的元素必定相邻,可以直接利用循环或递归的方法跳过重复结点,只要做一个简单的判断即可。
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
Java实现:
/**
*
* @author ChopinXBP
* 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
* 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。
*
*/
import java.util.HashMap;
import java.util.LinkedList;
public class DeleteDuplication_55 {
public static class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ListNode pHead = new ListNode(0);
ListNode p1= new ListNode(0);
ListNode p2= new ListNode(2);
ListNode p3= new ListNode(2);
ListNode p4= new ListNode(3);
ListNode p5= new ListNode(3);
ListNode p6= new ListNode(5);
pHead.next = p1;
p1.next = p2;
p2.next = p3;
p3.next = p4;
p4.next = p5;
p5.next = p6;
pHead = deleteDuplication(pHead);
while(pHead != null) {
System.out.print(pHead.val + " ");
pHead = pHead.next;
}
}
//利用HashMap(可用于不排序链表)
public static ListNode deleteDuplication(ListNode pHead)
{
if(pHead == null) return null;
HashMap<Integer, Integer> map = new HashMap<>();
LinkedList<Integer> dupnum = new LinkedList<>();
ListNode p = pHead;
int loc = 0;
while(p != null) {
if(map.containsKey(p.val)) {
//不重复放入第一次重复的结点
if(map.get(p.val) != -1) {
dupnum.add(map.get(p.val));
map.put(p.val, -1);
}
dupnum.add(loc);
}else {
map.put(p.val, loc);
}
loc++;
p = p.next;
}
//若链表不排序,对结点位置容器进行排序即可,时间复杂度取决于排序复杂度
//Collections.sort(dupnum);
//注意可能不保留头结点,设定一个辅助头结点,其next指向pHead
ListNode newhead = new ListNode(-1);
newhead.next = pHead;
p = newhead;
loc = -1;
while(!dupnum.isEmpty()) {
int step = dupnum.pollFirst() - loc;
//指向应删除结点前一位
for(int i = 0; i < step - 1; i++) {
p = p.next;
loc++;
}
p.next = p.next.next;
loc++;
}
return newhead.next;
}
// 利用递归
public static ListNode deleteDuplication2(ListNode pHead) {
// 只有0个或1个结点,则返回
if (pHead == null || pHead.next == null) {
return pHead;
}
// 当前结点是重复结点
if (pHead.val == pHead.next.val) {
ListNode pNode = pHead.next;
while (pNode != null && pNode.val == pHead.val) {
// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
pNode = pNode.next;
}
// 从第一个与当前结点不同的结点开始递归
return deleteDuplication(pNode);
}
// 当前结点不是重复结点
else {
// 保留当前结点,从下一个结点开始递归
pHead.next = deleteDuplication(pHead.next);
return pHead;
}
}
//利用循环
public static ListNode deleteDuplication3(ListNode pHead) {
if (pHead == null || pHead.next == null) {
return pHead;
}
ListNode Head = new ListNode(0);
Head.next = pHead;
ListNode pre = Head;
ListNode last = Head.next;
while (last != null) {
if (last.next != null && last.val == last.next.val) {
// 找到最后的一个相同节点
while (last.next != null && last.val == last.next.val) {
last = last.next;
}
pre.next = last.next;
last = last.next;
} else {
pre = pre.next;
last = last.next;
}
}
return Head.next;
}
}
C++实现示例:
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead==NULL)
return NULL;
if (pHead!=NULL && pHead->next==NULL)
return pHead;
ListNode* current;
if ( pHead->next->val==pHead->val){
current=pHead->next->next;
while (current != NULL && current->val==pHead->val)
current=current->next;
return deleteDuplication(current);
}
else {
current=pHead->next;
pHead->next=deleteDuplication(current);
return pHead;
}
}
};
#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#