开始做LinkedList题型。用Java写的时候空指针是null,可以在开头加一个dummy node方便处理第一个node,以及可以直接用题目给的head进行遍历
8. Remove Nth Node From End of List (19)
大体思路是,对右数第n个node,先创建一个post指针走n步,然后再用一个pre指针从头开始和post一起走。当post走到最后一个node时(post.next == null),pre.next就是要remove的node。注意要考虑n大于list长度的情况。还有要注意的是,如果不加dummy node,则要考虑remove head node的情况(判断条件:循环时 i==n && post == null)。时间复杂度O(N),空间复杂度O(1)。
Java的码:
public ListNode removeNthFromEnd(ListNode head, int n) {
if (head == null || n < 1 ) return head;
ListNode dummy = new ListNode(0, head);
ListNode post = dummy;
for (int i = 0; i < n && post != null; ++i) {
post = post.next;
}
if (post == null) {
return dummy.next;
} else {
ListNode pre = dummy;
while (post.next != null) {
pre = pre.next;
post = post.next;
}
pre.next = pre.next.next;
return dummy.next;
}
}
P.S. 不加dummy node的话,post移动后的代码如下
if (i < n && post == null) {
return head;
} else if (i == n && post == null) {
return head.next;
} else {
ListNode pre = head;
while (post.next != null) {
pre = pre.next;
post = post.next;
}
ListNode nextNode = pre.next.next;
pre.next.next = null;
pre.next = nextNode;
return head;
}
9. Remove Duplicates from Sorted Array (26)
左右指针。左指针指0,右指针从1开始遍历。如果右指针的值等于左指针的值则跳过,否则右指针的值填到左指针指着的空里,并且左指针右进一格。时间复杂度O(N),空间复杂度O(1)。
Java的码:
public int removeDuplicates(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int left = 0;
for (int right = 1; right < nums.length; ++right) {
if (nums[right] != nums[left]) nums[++left] = nums[right];
}
return left + 1;
}
10. Remove Element (27)
与前一题同样思路。左右指针,右指针遍历,所指的值不等于val时copy到左指针的位置。或者,since这道题不要求返回的结果按照原序,也可以直接将每个val与array末尾的值进行调换,然后手动缩小array的size。时间复杂度O(N),空间复杂度O(1)。
解法一:
public int removeElement(int[] nums, int val) {
if (nums == null || nums.length == 0) {
return 0;
}
int left = 0;
for (int right = 0; right < nums.length; ++right) {
if (nums[right] != val) {
nums[left++] = nums[right];
}
}
return left;
}
解法二:
public int removeElement(int[] nums, int val) {
int i = 0;
int n = nums.length;
while (i < n) {
if (nums[i] == val) {
nums[i] = nums[n - 1];
--n;
} else {
++i;
}
}
return n;
}
11. Partition List (86)
利用dummy node的思想,创建两个dummy node,一个接上所有 值小于x的node,另一个接上其他的node。用head遍历原先的linked list,检查其val的大小,将其拆下来接到对应的dummy node后面,最后两个sub-list合并即可。时间复杂度O(N),空间复杂度O(1)。
Java的码:
public ListNode partition(ListNode head, int x) {
if (head == null) return head;
ListNode dummyLess = new ListNode(0);
ListNode lessPre = dummyLess;
ListNode dummyGreater = new ListNode(0);
ListNode greaterPre = dummyGreater;
while (head != null) {
if (head.val < x) {
lessPre.next = head;
lessPre = lessPre.next;
} else {
greaterPre.next = head;
greaterPre = greaterPre.next;
}
head = head.next;
}
lessPre.next = dummyGreater.next;
greaterPre.next = null;
return dummyLess.next;
}