leetcode上有四道关于移除有序序列中重复数字的题目,其中两道为数组结构,两道为链表结构,分别为:
(1)Remove Duplicates from sorted array I:移除一个有序数组中的重复数字,并且返回新数组的大小。
(2)Remove Duplicates from sorted array II:移除一个有序数组中的重复数字,并且返回新数组的大小,和上道题目不同的是每个数字可以最多重复两次出现。
(3)Remove Duplicates from sorted list I:移除一个有序链表中的重复数字,并且返回首节点。
(4)Remove Duplicates from sorted list II:移除一个有序链表中有重复数字出现的节点,并且返回首节点。
以下针对这四道题目分别进行分析。
题目一:Remove Duplicates from Sorted Array
Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
For example,
Given input array A = [1,1,2]
,
Your function should return length = 2
,
and A is now [1,2]
.
解析:移除一个有序数组中的重复数字,并且返回新数组的大小。很简单,用一个临时变量temp记录当前数组的值,将下一个值与该值比较,判断是否能进入新数组。
Java AC代码如下:
public class Solution { public int removeDuplicates(int[] A) { if(A==null || A.length==0){ return 0; } int result = 1; int temp = A[0]; for(int i=1;i<A.length;i++){ if(temp<A[i]){ A[result++] = A[i]; temp = A[i]; } } return result; } }
题目二:Remove Duplicates from Sorted Array II
Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?
For example,
Given sorted array A = [1,1,1,2,2,3]
,
Your function should return length = 5
,
and A is now [1,1,2,2,3]
.
解析:移除一个有序数组中的重复数字,并且返回新数组的大小,和上道题目不同的是每个数字可以最多重复两次出现。因此,可以添加一个布尔变量ifRepeated来记录是否出现数字重复。
Java AC代码:
public class Solution { public int removeDuplicates(int[] A) { if (A == null || A.length == 0) { return 0; } boolean ifRepeated = false; int curPos = 0; for (int i = 1; i < A.length; i++) { if (A[i] != A[curPos]) { ifRepeated = false; curPos++; A[curPos] = A[i]; } else if (!ifRepeated) { ifRepeated = true; curPos++; A[curPos] = A[i]; } } return curPos + 1; } }
题目三:Remove Duplicates from Sorted List
Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given 1->1->2
, return 1->2
.
Given 1->1->2->3->3
, return 1->2->3
.
解析:移除一个有序链表中的重复数字,并且返回首节点。该题的主要思路是用两个节点pre,cur分别记录已完成链表的末端节点和当前遍历到的节点。注意如果当前节点cur是个重复节点,要把pre.next置为null。
Java AC代码如下:
public class Solution { public ListNode deleteDuplicates(ListNode head) { if (head == null || head.next == null) { return head; } ListNode pre = head; ListNode cur = pre.next; while (cur != null) { if (cur.val != pre.val) { pre.next = cur; pre = cur; }else{ pre.next = null; } cur = cur.next; } return head; } }
题目四:Remove Duplicates from Sorted List II
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given 1->2->3->3->4->4->5
, return 1->2->5
.
Given 1->1->1->2->3
, return 2->3
.
解析:移除一个有序链表中有重复数字出现的节点,并且返回首节点。对于头节点可能不在输出链表中的题目,推荐使用“哑节点”dummy来做标记。pre和cur分别记录两个前后节点,如果两个节点的值不同,则根据布尔变量ifDulipcated判断pre节点是否可以加入到结果链表中;如果两个节点的值相同,则要将ifDulipcated标记为true。
注意当pre这个节点不能添加到结果链表中时,要用point.next = null 将当前节点断开。
Java AC代码:
public class Solution { public ListNode deleteDuplicates(ListNode head) { if (head == null || head.next == null) { return head; } ListNode pre = head; ListNode cur = pre.next; ListNode point = new ListNode(-1); ListNode dummy = point; boolean ifDuplicated = false; while (cur != null) { if (cur.val != pre.val) { if (!ifDuplicated) { point.next = pre; point = point.next; } else { point.next = null; } ifDuplicated = false; } else { point.next = null; ifDuplicated = true; } pre = pre.next; cur = cur.next; } if (!ifDuplicated) { point.next = pre; } return dummy.next; } }