赞
踩
先说下一个节点的结构:一个val域和一个next域
- public class ListNode {
- int val;
- ListNode next = null;
- public ListNode(int val) {
- this.val = val;
- }
- }
一、已知链表的头节点,将链表进行逆序。(不可以申请额外的空间)
- public static ListNode reverseList(ListNode node) {
- ListNode pre = null;
- ListNode pNext = null;
- while(node != null) {
- pNext = node.next;
- node.next = pre;
- pre = node;
- node = pNext;
- }
- return pre;
- }
二、已知链表的头节点,将链表从位置m到n逆序。注意:1<=m<=n<=链表长度(不允许申请额外空间)
思路:主要是要找到逆序的头节点和尾巴,以及头节点的前驱节点,和尾节点的后置节点
注意:如果m=1,说明是从第一个节点开始,那么就需要修改头节点
- public static ListNode reverseListBetween(ListNode node,int m,int n) {
- int index = 1;
- ListNode p = node;
- ListNode pre = null;
- while(index <= n) {
- if(index == m) {
- ListNode temp = p;
- ListNode tempPre = null;
- ListNode tempNext = null;
- for(int i = m;i <= n;i++) {//开始进行节点的逆序
- tempNext = temp.next;
- temp.next = tempPre;
- tempPre = temp;
- temp = tempNext;
- }
- if(pre == null) {//说明是从头节点就开始翻转
- p.next = temp;
- node = tempPre;//修改下头节点
- }else {
- pre.next = tempPre;
- p.next = temp;
- }
- index = n;
- }
- pre = p;
- p = p.next;
- index++;
- }
- return node;
- }
三、求两个链表公共的节点,若没有则返回null
解题思路:给个图就能知道!!!!从相同的位置开始判断。交点之后都是相同的。
- public static ListNode getIntersectionNode(ListNode node1,ListNode node2) {
- //先求两个链表的长度
- int len1 = getLengthOfList(node1);
- int len2 = getLengthOfList(node2);
- //将指针移动到相同的位置
- if(len1 > len2) {
- for(int i = 0; i < len1 - len2;i++)
- node1 = node1.next;
- }else {
- for(int i = 0; i < len2 - len1;i++)
- node2 = node2.next;
- }
- //找相同的节点
- while(node1 != null && node2 != null) {
- if(node1 == node2)
- return node1;
- node1 = node1.next;
- node2 = node2.next;
- }
- return null;
- }
- public static int getLengthOfList(ListNode node) {
- int len = 0;
- ListNode p = node;
- while(p != null) {
- len++;
- p = p.next;
- }
- return len;
- }
四、判断一个链表中是否有环,若有则返回环的入口,若没有则返回null
思路:设置快慢指针。
- public static ListNode detectCycle(ListNode node) {
- ListNode fast = node;
- ListNode low = node;
- while(low!=null && fast!=null && low.next != null && fast.next !=null) {
- low = low.next;
- fast = fast.next.next;
- if(low == fast) {
- //设置一个指针从头节点开始
- ListNode temp = node;
- while(temp != low) {
- temp = temp.next;
- low = low.next;
- }
- return temp;
- }
- }
- return null;
- }
五、链表划分:给定一个值x,将所有小于x的节点放在大于或等于x的节点前,且要保持这些节点原来的相对位置
解题思路:若是数组的话,实际上修改下排序的规则,并选择一种稳定的排序即可,但是链表采用排序的方式就会稍微复杂。实际上可以设置两个节点,遍历链表,将小于x的节点连接到一个节点,将大于或等于x的节点连接到另外一个节点,最后再将两个链表合并。
- public static ListNode partition(ListNode node,int val) {
- ListNode A = new ListNode(val);
- ListNode B = new ListNode(val);
- ListNode p1 = A;
- ListNode p2 = B;
- while(node != null) {
- if(node.val < val) {
- p1.next = node;
- p1 = p1.next;
- }else {
- p2.next = node;
- p2 = p2.next;
- }
- node = node.next;
- }
- p1.next = B.next;
- p2.next = null;
- return A.next;
- }
六、复杂链表的复制。
结点结构有三部分:一个值域 一个next域,一个随即域 ,指向任意节点。
- public class RandomListNode {
- int val;
- RandomListNode next = null;
- RandomListNode random = null;
- public RandomListNode(int val) {
- this.val = val;
- }
- }
- public static RandomListNode copyRandomListNode(RandomListNode node) {
- if(node == null)
- return null;
- //先复制节点
- RandomListNode p = node;
- while(p != null) {
- RandomListNode temp = new RandomListNode(p.val);
- temp.next = p.next;
- p.next = temp;
- p = p.next.next;
- }
- //复制节点的指向
- p = node;
- while(p != null) {
- if(p.random != null) {
- p.next.random = p.random.next;
- }
- p = p.next.next;
- }
- //拆分
- p = node;
- RandomListNode head = p.next;
- RandomListNode t = head;
- while(t.next != null) {
- p.next = t.next;
- t.next = t.next.next;
- p = p.next;
- t = t.next;
- }
- p.next = null;
- return head;
- }
七、两个排序链表的合并,合并后任然是有序的
- public static ListNode mergeTwoLists(ListNode node1,ListNode node2) {
- if(node1 == null)
- return node2;
- if(node2 == null)
- return node2;
- ListNode p = null;
- if(node1.val < node2.val) {
- p = node1;
- node1 = node1.next;
- }else {
- p = node2;
- node2 = node2.next;
- }
- ListNode t = p;
- while(node1 != null && node2 != null) {
- if(node1.val < node2.val) {
- t.next = node1;
- node1 = node1.next;
- }else {
- t.next = node2;
- node2 = node2.next;
- }
- t = t.next;
- }
- //退出时,至少有一个链表结束遍历了
- if(node1 != null) {
- t.next = node1;
- }
- if(node2 != null) {
- t.next = node2;
- }
- return p;
- }
八、链表的k逆序问题:每k个节点之间进行逆序,最后不足k个节点不逆序
- public static ListNode reverseK(ListNode node,int k) {
- //判断是否有k个节点,不足k个节点 直接返回头节点
- int index = 0;
- ListNode p = node;
- while(p != null) {
- index++;
- p = p.next;
- }
- if(index < k)
- return node;
- p = node;
- ListNode temp = p;//保存下当前的头节点
- ListNode pre = null;
- ListNode pNext = null;
- for(int i = 0; i < k;i++) {
- pNext = p.next;
- p.next = pre;
- pre = p;
- p = pNext;
- }
- //新的头节点为pre;
- temp.next = reverseK(p,k);//当前k个节点的尾节点的下一个为下k个节点逆序后的头节点
- return pre;
- }
九、删除链表中指定的值,返回清除后的头节点
注意:是否删除的头节点
- public static ListNode clearList(ListNode node,int val) {
- ListNode p = node;
- ListNode pre = null;
- while(p != null) {
- if(p.val == val) {
- //判断是否是头节点
- if(p == node) {
- node = p.next;
- p = node;
- }else {
- pre.next = p.next;
- p = p.next;
- }
- }else {
- pre = p;
- p = p.next;
- }
- }
- return node;
- }
十、判断链表是否是回文
- public static boolean isPalindrome(ListNode node) {
- ArrayList<ListNode> list = new ArrayList<>();
- ListNode p = node;
- while(p != null) {
- list.add(p);
- p = p.next;
- }
- for(int i = 0; i < list.size()/2;i++) {
- if(list.get(i).val != list.get(list.size()-1-i).val)
- return false;
- }
- return true;
- }
感觉差不多了 反正链表很简单 就这样吧
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。