82, 题目:
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.
本题是要将所有出现的重复元素全部删除,思路比较简单,就是获取重复元素的起始、终止位置,然后直接将其前面的节点指向其后面的节点就可以了。代码如下所示:
public ListNode deleteDuplicates(ListNode head) {
ListNode pre = new ListNode(0);
pre.next = head;
//使用left来记录左侧最后面的值。
ListNode cur=head, left=pre;
while(cur != null && cur.next != null){
if(cur.val != cur.next.val){
left = cur;
cur = cur.next;
}else{
while(cur.next != null && cur.val == cur.next.val)
cur = cur.next;
left.next = cur.next;
cur = cur.next;
}
}
return pre.next;
}
此外还可以使用递归的方法来解决此题,思路是一样的,代码如下所示:
public ListNode deleteDuplicates1(ListNode head) {
if (head == null) return null;
if (head.next != null && head.val == head.next.val) {
while (head.next != null && head.val == head.next.val) {
head = head.next;
}
return deleteDuplicates(head.next);
} else {
head.next = deleteDuplicates(head.next);
}
return head;
}
445题,
You are given two non-empty linked lists representing two non-negative integers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.
Example:
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7
这道题目是将两个数相加并返回结果,与I不同的是本题数字是反序存放的,所以我们首先要判断出二者的数字位置对应关系,此外还有一个难点就是进位如何处理。而且我们不能从链表的结尾处向前遍历,给结题带来了很大的不便。我已开始想到了递归的方法,因为递归会先计算最后的结果然后一层层反向传递回来。这样就可以解决无法从最后开始计算的问题,并且可以将仅为信息逐层传递==
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode res = new ListNode(0);
ListNode list1=l1, list2=l2;
int len1=0, len2=0;
//计算两个链表的长度len1,len2
while(list1 != null){
list1 = list1.next;
len1 ++;
}
while(list2 != null){
list2 = list2.next;
len2 ++;
}
list1 = l1;list2=l2;
int flag = len1 > len2 ? dfs(list1, list2, len1-len2, res) :
dfs(list2, list1, len2 - len1, res);
//看最后一位是否产生进位,如果产生则在最前面加个1,否则直接返回
if (flag == 1){
res.val = 1;
return res;
}
return res.next;
}
public static int dfs(ListNode l1, ListNode l2, int offset, ListNode res){
//先将两个链表的差距抹平,offset表示链表的长度差
if(offset > 0){
res.next = new ListNode(0);
res = res.next;
//直接将链表的值加到res,如果要进位,则加1
int sum = l1.val + dfs(l1.next, l2, offset-1, res);
res.val = sum % 10;
return sum / 10;
}else{
if(l1 == null || l2 == null)
return 0;
res.next = new ListNode(0);
res = res.next;
//将两个链表对应的值进行求和,并加上下一位置产生的进位值
int sum = l1.val + l2.val + dfs(l1.next, l2.next, offset, res);
res.val = sum % 10;
return sum / 10;
}
}
这种方法可以击败13%的用户,然后我再discuss里面看到另外一种递归解法,可以击败85%的用户==感觉思路都是一样的,但是不知道差在哪里:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int size1 = getLength(l1);
int size2 = getLength(l2);
ListNode head = new ListNode(1);
// Make sure l1.length >= l2.length
head.next = size1 < size2 ? helper(l2, l1, size2 - size1) : helper(l1, l2, size1 - size2);
// Handle the first digit
if (head.next.val > 9) {
head.next.val = head.next.val % 10;
return head;
}
return head.next;
}
// get length of the list
public int getLength(ListNode l) {
int count = 0;
while(l != null) {
l = l.next;
count++;
}
return count;
}
// offset is the difference of length between l1 and l2
public ListNode helper(ListNode l1, ListNode l2, int offset) {
if (l1 == null) return null;
// check whether l1 becomes the same length as l2
ListNode result = offset == 0 ? new ListNode(l1.val + l2.val) : new ListNode(l1.val);
ListNode post = offset == 0 ? helper(l1.next, l2.next, 0) : helper(l1.next, l2, offset - 1);
// handle carry
if (post != null && post.val > 9) {
result.val += 1;
post.val = post.val % 10;
}
// combine nodes
result.next = post;
return result;
}
此外,我们还可以使用一些额外的数据结构来帮助解题,但是这就失去了链表的意义,所以跟题目关系不大,代码如下所示:
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
HashMap<Integer, Integer> hm1 = new HashMap<>(); //Store the 'index' and the value of List1
HashMap<Integer, Integer> hm2 = new HashMap<>(); //Store the 'index' and the value of List2
int i = 1, j = 1;
while(l1 != null){
hm1.put(i, l1.val);
l1 = l1.next;
i++;
}
while(l2 != null){
hm2.put(j, l2.val);
l2 = l2.next;
j++;
}
int carry = 0;
i--; j--;
ListNode head = null;
//Create new nodes to the front of a new LinkedList
while(i > 0 || j > 0 || carry > 0){
int a = i > 0 ? hm1.get(i) : 0;
int b = j > 0 ? hm2.get(j) : 0;
int res = (a + b + carry) % 10;
ListNode newNode = new ListNode(res);
newNode.next = head;
head = newNode;
carry = (a + b + carry) / 10;
i--; j--;
}
return head;
}
}