前言
###我做这类文章一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?建议灵神的题单和代码随想录)和记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!!
习题
1.反转偶数长度组的节点
题目链接:2074. 反转偶数长度组的节点 - 力扣(LeetCode)
题面:
分析:用数组存值的同时再开一个falg数组存一下每个节点所属的组,对于非最后一组来说,如果是偶数组,那么该组个数也是偶数个,进行翻转,对于最后一组,提前统计最后一组的个数,如果为偶数,就进行反转,反转过程中使用虚拟头节点更方便
/*** 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 reverseEvenLengthGroups(ListNode head) {int[] arr = new int[100005];int[] flag = new int[100005];int inz = 1;int index = 1;int count = 1;for(ListNode i = head;i!=null;i = i.next){flag[index] = inz;arr[index++] = i.val;if(count==inz){count = 1;inz++;}else{count++;}}int blag = flag[index-1];int lastcount = 1;for(int i = index-2;i>=1&&flag[i]==blag;i--)lastcount++;ListNode fhead = new ListNode(-1);fhead.next = head;ListNode pre = fhead;index = 1;int left = 3;boolean firstin = true;// System.out.println(blag+" "+lastcount);for(ListNode i = head;i!=null;i = i.next){if(flag[index]!=flag[index-1]){firstin = true;}if((flag[index]%2==0&&flag[index]!=blag)||(flag[index]==blag&&lastcount%2==0)){if(firstin){if(flag[index]==blag){left = index+lastcount-1;}else{left = index+flag[index]-1;}firstin = false;}ListNode node = new ListNode(arr[left--]);pre.next = node;pre = node;}else{pre.next = i;pre = i;}index++;}return fhead.next;}
}
2.旋转链表
题目链接:61. 旋转链表 - 力扣(LeetCode)
题面:
分析:可以通过计算出向右移动k个位置的头节点的值,然后遍历时,维护一个变量用于记录遍历当前节点的上一个节点(这里开一个虚拟头节点可以少一些考虑),当遍历到目标头节点时,让目标头节点的上一个节点指向空,然后遍历到的最后一个节点指向原头节点即可
/*** 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 rotateRight(ListNode head, int k) {if(head==null)return null;int count = 0;for(ListNode i = head;i!=null;i=i.next){count++;}int flag = k%count;int bindex = count-flag+1;int index = 1;ListNode fhead = new ListNode();fhead.next = head;ListNode pre = fhead;ListNode ans = null;for(ListNode i = head;i!=null;i =i.next){if(index==bindex){ans = i;ListNode node = null;pre.next = node;}if(index==count){i.next = fhead.next;}pre = i;index++;}return ans;}
}
3.交换链表中的节点
题目链接: 1721. 交换链表中的节点 - 力扣(LeetCode)
题面:
分析:找到正数和倒数两个节点的索引位置,并存一下值,这里用递归比较方便,然后遍历链表修改值
代码:
/*** 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 {ListNode head;int k;int zval = -1;int rval = -1;int r = 0;public ListNode swapNodes(ListNode head, int k) {this.head = head;this.k = k;recursion(head,1);int index = 1;for(ListNode i = head;i!=null;i=i.next){if(index==k){i.val = rval;}else if(index==r){i.val = zval;}index++;}return head;}public int recursion(ListNode node,int z){if(node==null)return 1;if(z==k){zval = node.val;}int r2 = recursion(node.next,z+1);if(r2==k){rval = node.val;r = z;}return r2+1;}
}
4.链表的中间节点
题目链接:876. 链表的中间结点 - 力扣(LeetCode)
题面:
分析:可以用递归分别统计节点的个数和答案节点的索引,在回溯过程中如果回溯到答案节点,返回
代码:
/*** 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 {int flag = -1;ListNode ans = null;public ListNode middleNode(ListNode head) {recursion(head,1);return ans;}public void recursion(ListNode node,int z){if(node==null){flag =(z-1)/2+1;return;}recursion(node.next,z+1);if(z==flag){ans = node;return;}}
}
5.删除链表的中间节点
题目链接: 2095. 删除链表的中间节点 - 力扣(LeetCode)
题面:
分析:快慢指针,慢指针每次走一步,快指针每次走两步,当快指针指向的位置是最后一个节点或者是null,此时慢指针更好指向中间节点,然后正常删除就行
代码:
/*** 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 deleteMiddle(ListNode head) {if(head==null||head.next==null)return null;ListNode pre = head;for(ListNode i = head ,j=head;i!=null;i=i.next){if(j==null||j.next==null){ListNode node = i.next;pre.next = node;break;} j=j.next.next;pre = i;}return head;}
}
6.回文链表
题目链接:234. 回文链表 - 力扣(LeetCode)
题面:
分析:使用StringBuilder的reverse方法
代码:
/*** 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 boolean isPalindrome(ListNode head) {StringBuilder sb = new StringBuilder();for(ListNode i = head;i!=null;i=i.next){sb.append(i.val+"");}// System.out.println(sb.reverse().toString());// System.out.println(sb.toString());return sb.toString().equals(sb.reverse().toString());}
}
后言
上面是力扣数据结构相关,下一篇是其他的习题,希望有所帮助,一同进步,共勉!