一、计算链表中节点个数
/**
* @return count 链表中的结点个数
*/
public static int getLength(Node head) {
if(head==null) {
return 0;
}
Node temp =head
int count=0;
while(temp!=null){
count++;
temp=temp.next;
}
return count;
}
二、返回倒数第k个节点
方法一:计算链表中的结点个数sum,然后遍历sum-k次即可.
方法二:通过维护一个定长区间,移动区间右端为空,左端点即为要返回的结点
/**
* @param k
* @param head
* @return 返回倒数第k个节点
*/
public Node findIndexNode(int k,Node head){
if(head.next == null){
System.out.println("链表为空");
return:
}
int size = getLength(head);
int num = size-k; //要遍历的次数
Node temp = head.next;
for(int i =0;i<num;i++){
temp=temp.next;
}
return temp;
}
//方法二
public Node findIndexNode(int k ,Node head){
if(head == null){
return null;
}
Node temp = head;
for(int i = 0 ;i< k-1;i++){
temp = temp.next;
}
Node slow = head;
while(temp!=null){
slow = slow.next;
temp =temp.next;
}
return slow;
}
三、单链表的反转
public static void reverse(Node head) {
if(head.next ==null||head.next.next==null){
return;
}
Node cur=head.next;
Node next=null;
Node newList=new Node(0);
while(cur!=null){
next=cur.next; //next保存下一节点
cur.next =newList.next; //将cur的下一节点加入新链表的最前端
newList.next=cur; //当前节点链接到新链表
cur=next; //cur指向下一节点
}
head.next=newList.next;
}
四、从尾到头打印单链表
public static void reversePrint(Node head) {
Stack<Node> stack = new Stack();
Node temp = head;
//将所有节点压入栈
while (temp != null) {
stack.push(temp);
temp = temp.next;
}
//当栈不为空时,弹栈并显示
while (!stack.isEmpty()){
System.out.println(stack.pop());
}
}
五、删除排序链表中的重复元素
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
public ListNode deleteDuplicates(ListNode head) {
if(head == null){
return null;
}
ListNode node = head;
while(node!=null&&node.next!=null){
if(node.val==node.next.val){
node.next= node.next.next;
}
else{
node=node.next;
}
}
return head;
}
六、判断链表是否有环
快指针比慢指针每次走两步
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) {
return false;
}
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
七、返回环形链表中的第一个结点(不带头结点)
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
public ListNode detectCycle(ListNode head) {
if( head == null || head.next ==null){
return null;
}
ListNode slow =head;
ListNode fast= head;
while(fast!=null){
slow = slow.next;
if(fast.next != null){
fast=fast.next.next;
}else{
return null;
}
if(fast == slow){
ListNode temp = head;
while(temp!=slow){
temp=temp.next;
slow=slow.next;
}
return temp;
}
}
return null;
八、两两交换链表中的结点(不带头结点)
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
public ListNode swapPairs(ListNode head) {
ListNode pre =new ListNode(0);
pre.next =head;
ListNode temp = pre;
while(temp.next!=null&&temp.next.next!=null){
ListNode node1 = temp.next;
ListNode node2=temp.next.next;
temp.next= node2; //交换前后结点
node1.next =node2.next;
node2.next =node1;
temp=node1;
}
return pre.next;
}
九、删除链表中的第n个结点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode temp = new ListNode(0,head);
int size =len(head);
int len =size-n;
ListNode node =temp;
for(int i = 0;i<len;i++){
node=node.next;
}
node.next=node.next.next;
return temp.next;
}
public int len(ListNode node){
int sum=0;
while(node!=null){
sum++;
node=node.next;
}
return sum;
}
}
十、给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
示例 1:
输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
令odd.next=even
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode oddEvenList(ListNode head) {
if(head ==null)
return null;
ListNode odd = head;
ListNode even = head.next;
ListNode temp =even;
while(temp!=null&&temp.next!=null){
odd.next = temp.next;
odd=odd.next;
temp.next=odd.next;
temp=temp.next;
}
odd.next = even;
return head;
}
}
排序链表
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
//利用归并排序
class Solution {
public ListNode sortList(ListNode head) {
if(null == head || null == head.next)
return head;
ListNode fast =head;
ListNode slow =head;
//根据快慢指针找到中点
while(fast.next!=null&&fast.next.next!=null){
slow = slow.next;
fast= fast.next.next;
}
ListNode temp = slow.next;
slow.next = null; //进行左右分离
ListNode left =sortList(head); //左边进行排序
ListNode right =sortList(temp);//排序右边
ListNode pre = new ListNode(0);
ListNode res = pre;
//进行链表合并
while(left != null &&right != null){
if(left.val <right.val){
pre.next =left;
left =left.next;
}else{
pre.next =right;
right=right.next;
}
pre = pre.next;
}
if(left == null){
pre.next =right;
}else{
pre.next = left;
}
return res.next;
}
}
先寻找链表的中间节点,然后将后半部分逆置,两边再逐一比较
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class PalindromeList {
public boolean chkPalindrome(ListNode A) {
if(A == null){
return false;
}
//找中间节点
ListNode fast = A;
ListNode slow = A;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode cur = slow.next;
while(cur != null){
ListNode next = cur.next;
cur.next = slow;
slow = cur;
cur = next;
}
while(A != slow){
//当链表节点个数为偶数时判断是否w
if(A.next == slow){
return true;
}
if(A.val != slow.val){
return false;
}
A = A.next;
slow = slow.next;
}
return true;
}
}