Java数据结构和算法之删除链表中的重复元素

本文介绍了一种高效的数据去重算法,适用于单链表结构中绝对值相等的节点去重。通过使用辅助数组标记节点数据,实现了一趟扫描即可完成去重过程,显著提升了处理效率。

题目:用单链表保存m个整数,节点的数据结构为(data,next),且|data| <= n(n为正整数)。现要求设计一个时间复杂度尽可能高效的算法,对于链表中data的绝对值相等的节点,仅保留第一次出现的节点而删除其余绝对值相等的节点。

解题思路: 数据大小有范围限制,因此可以设置一个辅助数组记录该数据是否已出现,如果已经出现,则删除;如果未出现,则标记。一趟扫描完成。

代码如下:
package com.guigu.LinkedListDemo;

public class DistinctDataDemo {
	public static void main(String[] args) {
		
		
		// 实例化一个链表对象
		DisLinkedList disLinkedList = new DisLinkedList();
		
		DisNode node1 = new DisNode(10);
		DisNode node2 = new DisNode(-10);
		DisNode node3 = new DisNode(5);
		DisNode node4 = new DisNode(8);
		DisNode node5 = new DisNode(-5);
		DisNode node6 = new DisNode(-9);
		DisNode node7 = new DisNode(9);
		
		disLinkedList.add(node1);
		disLinkedList.add(node2);
		disLinkedList.add(node3);
		disLinkedList.add(node4);
		disLinkedList.add(node5);
		disLinkedList.add(node6);
		disLinkedList.add(node7);
		
		System.out.println("去重前的链表:");
		disLinkedList.list();
		
		System.out.println();
		distinctDataOfLinkedList(disLinkedList);
		
		System.out.println("去重后的链表:");
		disLinkedList.list();
	}
	
	public static void distinctDataOfLinkedList(DisLinkedList list) {
		int n = 10; // 代表链表的容量
		// 定义一个数组用来标记数据是否存在
		int[] flag = new int[n + 1];
		
		DisNode p, q; // 定义两个指针
		p = list.head; // 让p指向head
		
		while(p.next != null) { // 退出条件
			int index = Math.abs(p.next.data); // 获得p后一个节点的数据
			if(flag[index] == 0) { // 如果对应标记为0, 则修改标记
				flag[index] = 1;
				p = p.next; // p 后移
			}else if(flag[index] == 1){ // 如果标记为1,说明该元素已经存在,执行删除操作
				q = p.next; // q指向待删除节点
				p.next = q.next; // p指向的节点直接指向待删除节点的后一个
			}
		}
	}
}


// 定义一个链表的实现类
class DisLinkedList {
	public DisNode head = new DisNode(0); // 链表的头结点
	
	// 添加节点
	public void add(DisNode disNode) {
		if(head == null) { // 第一个节点,直接让头指针指向它即可
			head.next = disNode;
		}
		// 定义一个辅助指针
		DisNode temp = head;
		while(true) {
			if(temp.next == null) { // 到了最后一个节点
				break;
			}
			temp = temp.next; // temp 后移
		}
		temp.next = disNode; // 将新节点加入链表
	}
	
	// 遍历链表
	public void list() {
		if(head == null) {
			System.out.println("链表为空"); // 判断链表是否为空
			return ;
		}
		DisNode cur = head.next; // 辅助指针
		System.out.print("head");
		while(cur != null) {
			System.out.printf("-> %d", cur.data);
			cur = cur.next; // cur后移
		}
	}
}

// 定义一个节点类
class DisNode {
	public int data; // 数据域
	public DisNode next; // 指向下一个节点
	
	// 构造器
	public DisNode(int data) {
		this.data = data;
	}
}
运行结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值