1.返回倒数第k个节点
题解:定义两个快慢指针或着快慢变量。1.让fast先走k-1步 2.fast走完,在跟show一起走
3. 走到fast.next == null结束,返回show.val
public int kthToLast(ListNode head, int k) {
if (k <=0 || head == null ) {
return -1;
}
ListNode fast = head;
ListNode show = head;
//fast先走k-1步
while (k-1 != 0) {
fast = fast.next;
if (fast == null) {
return -1;
}
k--;
}
//fast、show一起走
while (fast.next != null) {
fast = fast.next;
show = show.next;
}
return show.val;
}
2.回文链表
题解:1.找到中间节点吗
2.该链表为单向链表,所以需要把中间节点的后半部反转
3.在处理一些其它情况(链表为偶数)
public boolean isPalindrome(ListNode head) {
if (head == null) {
return true;
}
if (head.next == null) {
return true;
}
ListNode slow = head;
ListNode fast = head;
//找中间节点
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
ListNode car = slow.next;
//反转
while (car != null) {
ListNode curNext = car.next;
car.next = slow;
slow = car;
car = curNext;
}
while (head != slow) {
if (head.val != slow.val) {
return false;
}
//解决偶数链表
if (head.next == slow) {
return true;
}
if (head.val == slow.val){
head = head.next;
slow = slow.next;
}
}
return true;
}
3.删除链表的倒数第n个节点
题解:1.先找到要删除的倒数第n个节点
2.找删除节点的前一个节点 3.处理特殊情况
public ListNode removeNthFromEnd ( int n) {
if (n <= 0 || head == null) {
return null;
}
ListNode fast = head;
ListNode slow = head;
ListNode car = head;
int count = 1;
while (n-1 != 0) {
fast = fast.next;
//处理n大于size()
if (fast == null) {
return null;
}
n--;
}
//找倒数第n个节点
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
//找删除节点的前一个节点
if (car != slow) {
while (car.next != slow) {
if (car.next == null) {
return null;
}
car = car.next;
count++;
}
car.next = slow.next;
} else {
if ( n == count) {
head = head.next;
}
}
return head;
}
4.链表分割
题解: 1.用car遍历链表分割成两部分,节点放在<x || >= x
2.定义bs、be记录<x,as、ae记录 >= x,且bs和as永远都是两部分的头 、
3.处理一些特殊情况
public ListNode partition(ListNode head, int x) {
ListNode bs = null;
ListNode be = null;
ListNode as = null;
ListNode ae = null;
ListNode car = head;
while (car != null) {
if (car.val < x) {
if (bs == null) {
bs = car;
be = car;
} else {
be.next = car;
be = be.next;
}
} else {
if (as == null) {
as = car;
ae = car;
} else {
ae .next = car;
ae = ae.next;
}
}
car = car.next;
}
//如果链表没有出现小于X或大于等于X
if (bs == null) {
return as;
}
//第一段不为空
be.next = as;
if (as != null) {
ae.next = null;
}
return bs;
}
5.相交链表
题解:1.两个链表相交,不同点就是相交点之前的长度可能不同
2.求两个链表的长度
3.让长链表先走这两个链表的差(大于0)
public MySingleList.ListNode getIntersectionNode(MySingleList.ListNode headA, MySingleList.ListNode headB) {
MySingleList.ListNode bl = headA;
MySingleList.ListNode as = headB;
int lenA = 0; //记录链表长度
int lenB = 0;
//记录两链表的长度
while (bl != null) {
lenA++;
bl = bl.next;
}
while (as != null) {
lenB++;
as = as.next;
}
int let = lenA - lenB;
//while循环结束bl、as会为null,重新指向
bl = headA;
as = headB;
//1.let一定为正数 2.bl一定是长链表
if (let < 0) {
bl = headB;
as = headA;
let = lenB - lenA;
}
//bl先走
while (let > 0) {
bl = bl.next;
let--;
}
while (bl != as) {
bl = bl.next;
as = as.next;
}
return bl;
}
6.合并两个排序的链表
题解:1.定义一个新的节点,用的记录合并之后的head地址
2.定义一个temp起始放在新节点的位置,用来传递两个链表比较之后的指向
3.对一些特殊情况进行处理
public ListNode Merge (ListNode head1, ListNode head2) {
ListNode newHead = new ListNode(0);
ListNode temp = newHead;
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
temp.next = head1;
head1 = head1.next;
} else {
temp.next = head2;
head2 = head2.next;
}
temp = temp.next;
}
if (head1 != null && head2 == null) {
temp.next = head1;
}
if (head2 != null && head1 == null) {
temp.next = head2;
}
return newHead.next;
}
方法不唯一!!!