剑指offer第二版——面试题18(java)

面试题18:删除链表的节点

题目一 :在O(1)时间内删除链表节点——见【LeetCode 237. Delete Node in a Linked List & 剑指offer Q18

题目二:删除链表中重复的节点

题目描述:

在一个排序的链表中,如何删除重复的节点

如1→2→3→3→4→4→5  删除重复节点,重复节点不保留之后得到:1→2→5

分为三个部分:

① 删除链表中开头的第一类重复数字,如1 1 2 2 3 3 4 5 中,删除1 1 ,输出为节点2

② 找到链表第一个可保留的数字(节点),即删除从链表head开始的所有有重复的数字,直到遇到一个没有重复的数字(节点),如1 1 2 2 3 3 4 5中,返回4节点

③ 迭代地寻找链表中可保留的数字(节点),如1 1 2 2 3 3 4 5 中,先使用②找到第一个可保留的4,再使用②查找子串4 5中第一个可保留的5,将其连接为4 5,得到答案

【注意】在每次处理完后,如果需要比较node.val 要注意之前是否有让node=null的步骤,如果有,注意判断

// Q18 
public class Q18 {
	public static void main(String[] args) {
		ListNode head = getLink();
		showList(head);
		ListNode returnNode = deletDup(head);
		showList(returnNode);
	}
	
	//步骤3:迭代地寻找每个子串中需要保留的节点,并连接成链表
	public static ListNode deletDup(ListNode head) {
		// 至少为2个结点的才进行删除
		ListNode start = findNext(head);
		head = start;
		if(head==null) {
			return head;
		}
		while(start.next!=null) {
			ListNode temp = findNext(start.next);
			start.next = temp;
			start = temp;
		}
		return head;
	}
	
	// 步骤2:找到子列表中第一个保留的结点 如1 1 2 2 3 4 中的3 
	public static ListNode findNext(ListNode head) {
			int flag = 0;
			// 找到头部结点(删除头部有重复的元素)
			while(flag!=1) {
				int tempval = head.val;
				head = deletHeadOneDup(head);
				if(head==null) {return head;}
				if(tempval==head.val) {
					flag = 1;
				}
			}
		return head;
	}
	
	
	// 步骤1:删除重复链表开头的第一个重复数字 如1 1 2 2 3 4 中的1 1
	public static ListNode deletHeadOneDup(ListNode head) {
		if(head==null || head.next==null) {return head;}
		ListNode locnode = head;
		ListNode movenode = head.next;
		int flag = 0;
		
		// 链表开头就有重复,则改变链表开始位置
		while(locnode.val==movenode.val) {
			flag = 1;
			locnode = movenode;
			movenode = movenode.next;
			if(movenode==null) {
				break;
			}
		}
		if(flag==1) {
			head = movenode;
		}
			return head;
	}
	
	
	public static ListNode getLink() {
		System.out.println("input your Integer list:");
		Scanner scanner = new Scanner(System.in);
		ListNode node = new ListNode(0);
		ListNode head = node;
		while(scanner.hasNextInt()) {
			ListNode temp = new ListNode(scanner.nextInt());
			node.next = temp;
			node = temp;
		}
		return head.next;
	}
	
	
	public static void showList(ListNode node) {
		System.out.print("your list:");
		while(node!=null) {
			System.out.printf("%d ", node.val);
			node = node.next;
		}
		System.out.println();
	}
}


//数据结构
   public class ListNode {
     int val;
     ListNode next;
     ListNode(int x) 
         { val = x; 
         	 }
   	  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值