List
判断链表是否有环
一个快节点,一个慢节点,如果有环,快节点一定会追上慢节点
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast) return true;
}
return false;
}
}
删除一个节点
将要删除节点复制为下一个节点,并删除下一个节点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public void deleteNode(ListNode node) {
//将此节点复制为下一个节点,删除下一个节点
node.val = node.next.val;
ListNode temp = node.next.next;
node.next.next = null;
node.next = temp;
}
}
删除重复节点
Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head==null || head.next == null) return head;
ListNode node1 = head;
ListNode node2 = head.next;
while(node2 != null){
if(node1.val != node2.val){
node1 = node2;
node2 = node2.next;
}
else{
node1.next = node2.next;
node2 = node2.next;
}
}
return head;
}
}
获取两条链表的交点
将较长链表的长度减去较短链表的长度,然后较长链表头移动此长度,从此长度开始比较两个链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA = getLength(headA);
int lenB = getLength(headB);
int cutNum = lenA - lenB;
ListNode a = headA;
ListNode b = headB;
if(cutNum>0){
//A is longer
while(cutNum>0){
a = a.next;
cutNum--;
}
}
else if(cutNum<0){
//B is longer
cutNum = -cutNum;
while(cutNum>0){
b = b.next;
cutNum--;
}
}
//进行比较
while(a!=null){
if(a == b) return a;
a = a.next;
b = b.next;
}
return null;
}
public int getLength(ListNode head){
ListNode node = head;
int len = 0;
while(node!=null){
node = node.next;
len++;
}
return len;
}
}
删除指定节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode removeElements(ListNode head, int val) {
//传入空链表
if(head==null) return head;
//传入非空链表,但是节点全部都会被删除或者只剩一个节点
while(head!=null && head.val==val) head = head.next;
if(head==null || head.next==null) return head;
//至少存在两个节点其值和val不相同
ListNode node1 = head;
ListNode node2 = head.next;
while(node2!=null){
if(node2.val==val){
node2 = node2.next;
node1.next =node2;
}
else{
node1 = node2;
node2 = node2.next;
}
}
return head;
}
}
反转链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
if(head==null || head.next==null) return head;
ListNode pre = head;
ListNode cur = head.next;
ListNode temp = null;
pre.next = null;
while(cur!=null){
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
判断链表是否是回文链表
先找到链表的中点,然后以中点为起点反转之后的链表,然后逐项比较链表节点是否相等
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null || head.next==null) return true;
ListNode slow = head;
ListNode fast = head;
ListNode first = head;
ListNode last = head;
while(last.next!=null) last = last.next;
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
}
reverseList(slow);
while(first!=null && last!=null){
if(first.val!=last.val) return false;
first = first.next;
last = last.next;
}
return true;
}
public static void reverseList(ListNode head){
ListNode node1 = head;
ListNode node2 = head.next;
ListNode temp = null;
head.next = null;
while(node2 !=null){
temp = node2.next;
node2.next = node1;
node1 = node2;
node2 = temp;
}
}
}
拼接两个已经排序的链表
创建一个新链表,新链表的头是旧链表头中较小的那个,然后依次比较旧链表的各个节点值的大小,但是需要跳过已经成为新链表头的那个节点。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1==null) return l2;
if(l2==null) return l1;
ListNode head = l1.val>l2.val ? l2:l1;
ListNode helper = head;
ListNode head1 = l1.val>l2.val ? l2.next:l1.next;
ListNode head2 = l1.val>l2.val ? l1:l2;
while(head1!=null && head2!=null){
if(head1.val>head2.val){
helper.next = head2;
head2 = head2.next;
helper = helper.next;
}
else{
helper.next = head1;
head1 = head1.next;
helper = helper.next;
}
}
if(head1==null){
helper.next = head2;
}
else{
helper.next = head1;
}
return head;
}
}
右旋链表
首先找到倒数第n+1个节点,这个节点就是右旋链表的尾巴,这个链表的下一个节点就是新链表的头结点。
还要注意链表的边界情况,如链表为空或者只有一个节点或者k=0时,直接返回原链表。
如果k为链表长度,也返回原链表。
如果k大于链表长度,先用链表长度对k取模,然后再旋转链表。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head==null ||head.next==null || k==0)return head;
int length = getListLength(head);
if(k==length) return head;
if(k>length) return rotateRight(head,k%length);
ListNode newLastNode =getLastNNode(head,k+1);
ListNode helper = newLastNode.next;
while(helper.next!=null) helper = helper.next;
helper.next = head;
ListNode result = newLastNode.next;
newLastNode.next = null;
return result;
}
public ListNode getLastNNode(ListNode head,int n){
ListNode helper = head;
ListNode result = head;
for(int k=0;k<n;k++){
helper = helper.next;
}
while(helper!=null){
result = result.next;
helper = helper.next;
}
return result;
}
public int getListLength(ListNode head){
int length = 0;
while(head!=null){
head = head.next;
length++;
}
return length;
}
}