打印两个有序链表的公共部分
要求:打印两个有序链表的公共部分
给定两个有序链表的头指针head1和head2,打印两个链表的公共部分
public class PrintCommon {
public static void main(String[] args) {
Node node1 = new Node(1);
node1.next = new Node(5);
node1.next.next = new Node(8);
Node node2 = new Node(3);
node2.next = new Node(5);
node2.next.next = new Node(6);
node2.next.next.next = new Node(8);
printCommonPart(node1, node2);
}
/*要求:打印两个有序链表的公共部分
* 给定两个有序链表的头指针head1和head2,打印两个链表的公共部分
*/
public static void printCommonPart(Node head1,Node head2) {
while(head1 != null && head2 != null) {
if(head1.value == head2.value) {
System.out.println(head1.value);
head1 = head1.next;
head2 = head2.next;
}else if(head1.value > head2.value) {
head2 = head2.next;
}else {
head1 = head1.next;
}
}
}
}
class Node{
public Node next;
public int value;
public Node(int value) {
this.value = value;
}
}
在单链表和双链表中删除倒数第K个节点
要求:分别实现两个函数,一个可以删除单链表中倒数第K个节点,一个可以删除双链表中倒数第K个节点。
复杂度要求:时间复杂度O(n),空间复杂度O(1)
public class RemoveLastKthNode {
/*要求:分别实现两个函数,一个可以删除单链表中倒数第K个节点,一个可以删除双链表中倒数第K个节点。
* 时间复杂度O(n),空间复杂度O(1)
*/
public static void main(String[] args) {
/*Node node1 = new Node(3);
node1.next = new Node(5);
node1.next.next = new Node(6);
node1.next.next.next = new Node(8);
Node newNode = removeLastKthNode(node1,4);
while(newNode != null){
System.out.println(newNode.value);
newNode = newNode.next;
}*/
DoubleNode head = new DoubleNode(3);
DoubleNode head2 = new DoubleNode(6);
DoubleNode head3 = new DoubleNode(7);
DoubleNode head4 = new DoubleNode(8);
head.pre = null;
head.next = head2;
head2.pre = head;
head2.next = head3;
head3.pre = head2;
head3.next = head4;
head4.pre = head3;
head4.next = null;
DoubleNode newDoubleNode = removeLastKthDoubleNode(head,2);
}
public static Node removeLastKthNode(Node head,int k) {
if(k < 1 || head == null ) {
return head;
}
Node cur = head;
while(cur != null) {
cur = cur.next;
k--;
}
if(k == 0) {
return head.next;
}else if(k < 0) {
cur = head;
k++;
while(k != 0) {
cur = cur.next;
k++;
}
cur.next = cur.next.next;
}
return head;
}
public static DoubleNode removeLastKthDoubleNode(DoubleNode head,int k) {
DoubleNode cur = head;
while(cur != null) {
cur = cur.next;
k--;
}
if(k == 0) {
head.next.pre = null;
return head.next;
}else if(k < 0) {
cur = head;
while(k != 0) {
k++;
cur = cur.next;
}
cur.pre.next = cur.next;
if(cur.next != null) {
cur.next.pre = cur.pre;
}
}
return head;
}
}
//单链表
class Node{
public Node next;
public int value;
public Node(int value) {
this.value = value;
}
}
//双向链表
class DoubleNode{
public DoubleNode next;
public DoubleNode pre;
public int value;
public DoubleNode(int value) {
this.value = value;
}
}
删除链表的中间节点和a/b处的节点
public class RemoveMidNode {
/*要求:
* 给定链表的头节点head,实现删除链表的中间节点的函数(偶数个数节点时,删除前一个节点)
* 例如:1>2 删除节点1
* 1>2>3 删除节点2
* 1>2>3>4 删除节点2
* 进阶问题:
* 给定链表的头节点head,整数a和整数b,实现删除位于a/b处节点的函数
* 例如:1>2>3>4>5,假设a/b的值为r
* 如果r为0,不删除任何节点;
* 如果r在区间(0,1/5]上,删除节点1;
* 如果r在区间(1/5,2/5]上,删除节点1;
* 如果r在区间(2/5,3/5]上,删除节点1;
* 如果r在区间(3/5,4/5]上,删除节点1;
* 如果r在区间(4/5,1]上,删除节点1;
* 如果r大于1,不删除任何节点。
* */
public static void main(String[] args) {
Node node1 = new Node(3);
Node node2 = new Node(6);
Node node3 = new Node(9);
Node node4 = new Node(7);
Node node5 = new Node(8);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = null;
// Node newNode = removeMidNode(node1);
Node newNode = removeByRatio(node1, 3, 5);
while(newNode != null) {
System.out.println(newNode.value);
newNode = newNode.next;
}
}
public static Node removeMidNode(Node head) {
if(head == null || head.next == null) {
return head;
}
if(head.next.next == null) {
return head.next;
}
Node slow = head;
Node quick = head.next.next;
while(quick.next != null && quick.next.next != null) {
quick = quick.next.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
}
public static Node removeByRatio(Node head, int a, int b) {
if(a > b || a < 1 || head == null) {
return head;
}
int count = 0;
Node cur = head;
while(cur != null) {
count++;
cur = cur.next;
}
int n = (int) Math.ceil((double)(count*a)/b);
if(n == 1) {
return head.next;
}
cur = head;
while(n != 2) {
cur = cur.next;
n--;
}
cur.next = cur.next.next;
return head;
}
}
反转单向链表和双向链表
public class ReverseLinked {
/*要求: 反转单向链表和双向链表,时间复杂度为O(N),空间复杂度为O(1)
*/
public static void main(String[] args) {
/*Node node1 = new Node(3);
Node node2 = new Node(6);
Node node3 = new Node(9);
Node node4 = new Node(7);
Node node5 = new Node(8);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = null;
Node newNode = reverseLinked(node1);
while(newNode != null){
System.out.println(newNode.value);
newNode = newNode.next;
}*/
DoubleNode head = new DoubleNode(3);
DoubleNode head2 = new DoubleNode(6);
DoubleNode head3 = new DoubleNode(7);
DoubleNode head4 = new DoubleNode(8);
head.pre = null;
head.next = head2;
head2.pre = head;
head2.next = head3;
head3.pre = head2;
head3.next = head4;
head4.pre = head3;
head4.next = null;
DoubleNode newDoubleNode = reverseDoubleLinked(head);
while(newDoubleNode != null) {
System.out.print(newDoubleNode.value );
if(newDoubleNode.pre != null) {
System.out.print(" pre:"+newDoubleNode.pre.value);
}else {
System.out.print(" pre:"+newDoubleNode.pre);
}
if(newDoubleNode.next != null) {
System.out.print(" next:"+newDoubleNode.next.value);
}else {
System.out.print(" next:"+newDoubleNode.next);
}
newDoubleNode = newDoubleNode.next;
System.out.println();
}
}
//反转单向链表
public static Node reverseLinked(Node head) {
if(head == null || head.next == null) {
return head;
}
Node pre = null;
Node next = null;
while(head != null){
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
//反转双向链表
public static DoubleNode reverseDoubleLinked(DoubleNode head) {
if(head == null || head.next == null) {
return head;
}
DoubleNode pre = null;
DoubleNode next = null;
while(head != null) {
next = head.next;
head.next = pre;
head.pre = next;
pre = head;
head = next;
}
return pre;
}
}