链表的数据结构
/**
- Definition for singly-linked list.
- public class ListNode {
-
int val;
-
ListNode next;
-
ListNode(int x) { val = x; }
- }
*/
leetcode 2.两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
解题:试手好题,注意进位
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if(l1.val == 0 && l1.next == null){
return l2;
} else if(l2.val == 0 && l2.next == null){
return l1;
}
int carry = 0;
int val = 0;
ListNode first = null, last = null, newnode;
while( l1 != null || l2 != null) {
if (l1 == null){
val = l2.val + carry;
l2 = l2.next;
} else if(l2 == null) {
val = l1.val + carry;
l1 = l1.next;
} else {
val = l1.val + l2.val + carry;
l1 = l1.next;
l2 = l2.next;
}
if(val > 9 ){
carry = 1;
val = val - 10;
} else {
carry = 0;
}
newnode = new ListNode(val);
if(first == null) {
first = newnode;
last = newnode;
} else {
last.next = newnode;
last = newnode;
}
}
if(carry == 1){
newnode = new ListNode(carry);
last.next = newnode;
last = newnode;
}
return first;
}
leetcode 21.合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解题:同试手题,注意指针位置
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null)
return l2;
else if(l2 == null)
return l1;
ListNode first = null, last = null, newNode;
while(l1 != null || l2 != null) {
if(l1 == null) {
last.next = l2;
last = last.next;
break;
} else if(l2 == null) {
last.next = l1;
last = last.next;
break;
}
if(l1.val < l2.val) {
if(first == null) {
first = l1;
last = l1;
l1 = l1.next;
} else {
last.next = l1;
last = last.next;
l1 = l1.next;
}
} else {
if(first == null){
first = l2;
last = l2;
l2 = l2.next;
} else {
last.next = l2;
last = last.next;
l2 = l2.next;
}
}
}
return first;
}
leetcode 237.删除链表中的节点
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
现有一个链表 – head = [4,5,1,9]
示例 1:
输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
解题:链表基础
public void deleteNode(ListNode node) {
ListNode temp = node.next;
node.val = temp.val;
node.next = temp.next;
temp.next = null;
}
leetcode 876.链表的中间节点
给定一个带有头结点 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 :
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
提示:
给定链表的结点数介于 1 和 100 之间。
解题:遍历链表,找到中间节点位置
public ListNode middleNode(ListNode head) {
int count = 0;
ListNode pre = head;
while(pre != null){
count++;
pre = pre.next;
}
count = count / 2 + 1;
for(int i = 1; i < count;i++){
head = head.next;
}
return head;
}
leetcode 206.反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
递归法:从尾节点开始反转链表
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode next = head.next;
head.next = null;
ListNode first = reverseList(next);
next.next = head;
return first;
}
迭代法:从头节点开始反转链表
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode cur = head, firstnode = null;
while (cur != null){
ListNode temp = cur.next;
cur.next = firstnode;
firstnode = cur;
cur = temp;
}
return firstnode;
}