版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
1. 打印两个有序链表的公共部分
题目:
给定两个有序链表的头指针head1和head2,打印两个链表的公共部分。
代码:
package charpter2;
import java.util.List;
public class test1 {
public static void getPublic(ListNode head1, ListNode head2) {
while (head1 != null && head2 != null) {
if (head1.val > head2.val) {
head2 = head2.next;
} else if (head1.val < head2.val) {
head1 = head1.next;
} else {
System.out.println(head1.val);
head1 = head1.next;
head2 = head2.next;
}
}
}
public static void main(String[] args) {
ListNode listNode11 = new ListNode(1);
ListNode listNode12 = new ListNode(2);
ListNode listNode13 = new ListNode(3);
ListNode listNode14 = new ListNode(4);
ListNode listNode15 = new ListNode(5);
listNode11.next = listNode12;
listNode12.next = listNode13;
listNode13.next = listNode14;
listNode14.next = listNode15;
ListNode listNode21 = new ListNode(2);
ListNode listNode22 = new ListNode(3);
ListNode listNode23 = new ListNode(4);
ListNode listNode24 = new ListNode(5);
ListNode listNode25 = new ListNode(6);
listNode21.next = listNode22;
listNode22.next = listNode23;
listNode23.next = listNode24;
listNode24.next = listNode25;
getPublic(listNode11, listNode21);
}
}
2. 在单链表和双链表中删除倒数第K个节点
题目:
分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点
要求:
如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).
代码:
package charpter2;
import java.util.List;
public class test2 {
// 我的解法
public static ListNode deleteSingleKth(ListNode head, int K) {
ListNode temp = null;
ListNode head1 = head;
ListNode res = head1;
int n = 1;
while (head != null) {
if (n == K + 2) {
temp = head;
break;
}
head = head.next;
n++;
}
System.out.println("temp:" + temp.val);
while (temp != null) {
temp = temp.next;
head1 = head1.next;
}
System.out.println("head1:" + head1.val);
head1.next = head1.next.next;
return res;
}
// 最优解
public static ListNode deleteSingleKth1(ListNode head, int K) {
if (head == null || K < 1) {
return null;
}
ListNode cur = head;
while (cur != null) {
cur = cur.next;
K--;
}
if (K == 0) {
head = head.next;
}
if (K > 0) {
head = null;
}
if (K < 0) {
cur = head;
while (++K != 0) {
cur = cur.next;
}
head.next = head.next.next;
}
return head;
}
public static void main(String[] args) {
ListNode listNode11 = new ListNode(1);
ListNode listNode12 = new ListNode(2);
ListNode listNode13 = new ListNode(3);
ListNode listNode14 = new ListNode(4);
ListNode listNode15 = new ListNode(5);
listNode11.next = listNode12;
listNode12.next = listNode13;
listNode13.next = listNode14;
listNode14.next = listNode15;
ListNode ss = deleteSingleKth1(listNode11, 3);
while (ss != null) {
System.out.println(ss.val);
ss = ss.next;
}
}
}
对于双链表的调整,几乎与单链表的处理方式一样,注意last指针的重连即可。
3. 删除链表的中间节点
题目:
给定链表的头节点head, 实现删除链表的中间节点的函数
代码:
package charpter2;
import java.util.List;
public class test3 {
// 我的解法
public static ListNode deleteMid(ListNode head) {
if (head == null || head.next == null) {
return head;
}
if (head.next.next == null) {
return head.next;
}
int k = 0;
ListNode cur = head;
while (cur != null) {
cur = cur.next;
k++;
}
int mid = 0;
if (k % 2 == 0) {
mid = k / 2 - 2;
} else {
mid = k / 2 - 1;
}
ListNode temp = head;
ListNode res = temp;
while (head != null) {
if (mid == 0) {
temp = head;
break;
} else {
head = head.next;
mid--;
}
}
temp.next = temp.next.next;
return res;
}
// 最优解
public static ListNode deleteMidNode(ListNode head) {
if (head == null || head.next == null) {
return head;
}
if (head.next.next == null) {
return head.next;
}
ListNode pre = head;
ListNode cur = pre.next.next;
while (cur.next != null && cur.next.next != null) {
pre = pre.next;
cur = cur.next.next;
}
pre.next = pre.next.next;
return head;
}
public static void main(String[] args) {
ListNode listNode11 = new ListNode(1);
ListNode listNode12 = new ListNode(2);
ListNode listNode13 = new ListNode(3);
ListNode listNode14 = new ListNode(4);
ListNode listNode15 = new ListNode(5);
listNode11.next = listNode12;
listNode12.next = listNode13;
listNode13.next = listNode14;
listNode14.next = listNode15;
ListNode aa = deleteMidNode(listNode11);
System.out.println();
while (aa != null) {
System.out.println(aa.val);
aa = aa.next;
}
}
}
4. 反转单向链表
题目:
实现反转链表的函数
要求:
如果链表长度为N,时间复杂度要求为O(N), 额外空间复杂度要求为O(1)
代码:
package charpter2;
public class test4 {
public static ListNode reverseNode(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (head != null) {
cur = head.next;
head.next = pre;
pre = head;
head = cur;
}
return pre;
}
public static void main(String[] args) {
ListNode listNode11 = new ListNode(1);
ListNode listNode12 = new ListNode(2);
ListNode listNode13 = new ListNode(3);
ListNode listNode14 = new ListNode(4);
ListNode listNode15 = new ListNode(5);
listNode11.next = listNode12;
listNode12.next = listNode13;
listNode13.next = listNode14;
listNode14.next = listNode15;
ListNode res = reverseNode(listNode11);
while (res != null) {
System.out.println(res.val);
res = res.next;
}
}
}
5. 反转部分单向链表
题目:
给定一个单向链表的头节点head,以及两个整数from和to,在单向链表上把第from个节点到第to个节点这一部分进行反转。
代码:
package charpter2;
import java.util.Stack;
public class test5 {
public static ListNode reversePartNode(ListNode head, int from, int to) {
Stack<ListNode> stack = new Stack<>();
ListNode cur = head;
int k = 1;
// 将需要反转的节点放入栈中
while (head != null) {
if (k >= from && k <= to) {
stack.push(head);
head = head.next;
k++;
} else if (k < from) {
head = head.next;
k++;
} else {
break;
}
}
if (from > to || from < 1 || to > k - 1) {
return head;
}
int n = 1;
if (from == 1) {
cur = stack.pop();
}
ListNode res = cur;
while (n < from - 1) {
cur = cur.next;
n++;
}
while (!stack.empty()) {
cur.next = stack.pop();
cur = cur.next;
}
cur.next = head;
return res;
}
public static void main(String[] args) {
ListNode listNode11 = new ListNode(1);
ListNode listNode12 = new ListNode(2);
ListNode listNode13 = new ListNode(3);
ListNode listNode14 = new ListNode(4);
ListNode listNode15 = new ListNode(5);
listNode11.next = listNode12;
listNode12.next = listNode13;
listNode13.next = listNode14;
listNode14.next = listNode15;
ListNode res = reversePartNode(listNode11, 3, 5);
System.out.println();
while (res != null) {
System.out.println(res.val);
res = res.next;
}
}
}