大学思政类网站建设,wordpress 爆用户名,微信怎么弄自己的公众号,橙象品牌设计【本节目标】 1. ArrayList 的缺陷 2. 链表 3. 链表相关 oj题目 一. ArrayList的缺陷 上节课已经熟悉了ArrayList 的使用#xff0c;并且进行了简单模拟实现。通过源码知道#xff0c; ArrayList 底层使用数组来存储元素#xff1a; public class ArrayListE… 【本节目标】 1. ArrayList 的缺陷 2. 链表 3. 链表相关 oj题目 一. ArrayList的缺陷 上节课已经熟悉了ArrayList 的使用并且进行了简单模拟实现。通过源码知道 ArrayList 底层使用数组来存储元素 public class ArrayListE extends AbstractListEimplements ListE, RandomAccess, Cloneable, java.io.Serializable
{// ...
// 默认容量是10private static final int DEFAULT_CAPACITY 10;//...
// 数组用来存储元素transient Object[] elementData; // non-private to simplify nested class access// 有效元素个数private int size;public ArrayList(int initialCapacity) {if (initialCapacity 0) {this.elementData new Object[initialCapacity];} else if (initialCapacity 0) {this.elementData EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException(Illegal Capacity: initialCapacity);}}
// ...
} 由于其底层是一段连续空间当在 ArrayList 任意位置插入或者删除元素时就需要将后序元素整体往前或者往后 搬移时间复杂度为 O(n) 效率比较低因此 ArrayList 不适合做任意位置插入和删除比较多的场景 。因此 java集合中又引入了LinkedList 即链表结构。 二. 链表 1 链表的概念及结构 链表是一种物理存储结构上非连续 存储结构数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。 实际中链表的结构非常多样以下情况组合起来就有 8 种链表结构 单向------双向 循环------ 非循环 带头------ 不带头 1 单向或者双向 2 带头或者不带头 3 循环或者非循环 虽然有这么多的链表的结构但是我们重点掌握两种 : 无头单向非循环链表结构简单一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多 无头双向链表在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。 2 链表的实现 1、无头单向非循环链表实现 链表的基本表示 static class ListNode{public int val;public ListNode next;public ListNode(int data){this.valdata;}}public ListNode head;//链表的头 对应的方法 public interface IList {//头插法public void addFirst(int data);//尾插法public void addLast(int data);//任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data);//查找是否包含关键字key是否在单链表当中public boolean contains(int key);//删除第一次出现关键字为key的节点public void remove(int key);//删除所有值为key的节点public void removeAllKey(int key);//得到单链表的长度public int size();public void clear() ;public void display();
}实现对应的方法:
(1)display
public void display() {ListNode curhead;//不能改变头的引用while(cur!null){System.out.print(cur.val );curcur.next;}}
(2)size public int size() {int len0;ListNode curhead;while (cur!null){len;curcur.next;}return len;}
(3)contains public boolean contains(int key) {ListNode curnew ListNode(key);while(cur!null){if(cur.valkey){return true;}curcur.next;}return false;} (4)addFirst/头插 public void addFirst(int data) {ListNode listNodenew ListNode(data);//该节点是新的头节点listNode.nexthead;headlistNode;} (5)addFirst/尾插
public void addLast(int data) {ListNode listNodenew ListNode(data);if(headnull){headlistNode;return;}ListNode curhead;while(cur.next!null){curcur.next;}cur.nextlistNode;} (6)addIndex/任意位置插
public void addIndex(int index, int data) {int lensize();if (index0||indexlen){new IndexOutOfBoundary(index输入有误);return;}if(index0){addFirst(data);return;}if(indexlen){addLast(data);return;}int curLen0;ListNode curhead;ListNode listNodenew ListNode(data);while(curLenindex-1){curLen;curcur.next;}listNode.nextcur.next;cur.nextlistNode;} (7)remove public void remove(int key) {if(headnull){//链表为空return;}if(head.valkey){//删除的位置在头节点headhead.next;return;}ListNode prefindPreNodeOfKey(key);if(pre!null){ListNode delpre.next;//找到需要删除的节点pre.nextdel.next;}}private ListNode findPreNodeOfKey(int key){ListNode curhead;while(cur.next!null){//最后一个节点也已经判断过了if (cur.next.valkey){return cur;}curcur.next;}return null;} (8)removeAllKey public void removeAllKey(int key) {if(headnull){return;}ListNode prevhead;ListNode curhead.next;while(cur!null){if(cur.valkey){prev.nextcur.next;cur cur.next;}else {prevprev.next;cur cur.next;}}//把前面的除头节点之外的都删完之后删除头节点if (head.valkey){headhead.next;}} (9)clear public void clear() {ListNode curhead;while (cur!null){ListNode curNcur.next;cur.nextnull;//基本数据类型的val不需要回收curcurN;}} 三.链表相关题目 1. 删除链表中等于给定值 val 的所有节点。 /*** 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 removeElements(ListNode head,int data){if(headnull){return head;}ListNode prevhead;ListNode curhead.next;while(cur!null){if(cur.valdata){prev.nextcur.next;curcur.next;}else{prevprev.next;curcur.next;}}if(head.valdata){headhead.next;}return head;}}2. 反转一个单链表。 可以采取不停的进行头插将后面的节点不停的插到前面 /*** 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 reverseList(ListNode head) {if(headnull){return head;}ListNode curhead.next;head.nextnull;while(cur!null){ ListNode curNcur.next;cur.nexthead;headcur;curcurN;}return head;}
} 3. 给定一个带有头结点 head 的非空单链表返回链表的中间结点。如果有两个中间结点则返回第二个中间结点。 /*** 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 middleNode(ListNode head) {if(headnull){return head;}ListNode slowhead;ListNode fasthead;while(fast!nullfast.next!null){slowslow.next;fastfast.next.next;}return slow;}
} 4. 输入一个链表输出该链表中倒数第 k 个结点。 import java.util.*;/** public class ListNode {* int val;* ListNode next null;* public ListNode(int val) {* this.val val;* }* }*/public class Solution {/*** 代码中的类名、方法名、参数名已经指定请勿修改直接返回方法规定的值即可** * param pHead ListNode类 * param k int整型 * return ListNode类*/public ListNode FindKthToTail (ListNode pHead, int k) {int count0;ListNode fpHead;while(f!null){count;ff.next;}if(kcount||k0){return null;}if(pHeadnull){return pHead;}// write code hereListNode prevpHead;ListNode curpHead;while((k-1)!0){curcur.next;k--;}while(cur!nullcur.next!null){prevprev.next;curcur.next;}return prev;}
} 经过重新调整除了计算出有多少元素防止多删除之外可以在快指针走的时候就进行判断走太多就会超过限制那么就会走到空指针出也可以判断 while((k-1)!0){curcur.next;k--;if(curnull){return null;}} 5. 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 /*** 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 mergeTwoLists(ListNode list1, ListNode list2) {ListNode cur1list1;ListNode cur2list2;ListNode newHeadnew ListNode();ListNode tmpnewHead;if(cur1nullcur2null){return null;}while(cur1!nullcur2!null){if(cur1.valcur2.val){tmp.nextcur1;cur1cur1.next;tmptmp.next;}else{tmp.nextcur2;cur2cur2.next;tmptmp.next;}}if(cur1!null){tmp.nextcur1;cur1cur1.next;tmptmp.next;}if(cur2!null){tmp.nextcur2;cur2cur2.next;tmptmp.next;}return newHead.next;}
} 6. 编写代码以给定值 x 为基准将链表分割成两部分所有小于 x 的结点排在大于或等于 x 的结点之前 。 利用两个链表一个存放小于x的值一个存放大于x的值要注意的是最后的判断条件可能不存在小于x的则直接返回第二个链表且如果第二个链表不为空链表结尾要置空防止越界。 import java.util.*;/*
public class ListNode {int val;ListNode next null;ListNode() { }ListNode(int val) {this.val val;}
}*/
public class Partition {public ListNode partition(ListNode pHead, int x) {// write code hereListNode list1startnull;ListNode list1endnull;ListNode list2startnull;ListNode list2endnull;while(pHead!null){if(pHead.valx){if(list1startnull){list1startlist1endpHead;}else{list1end.nextpHead;list1endlist1end.next;}}else{if(list2startnull){list2startlist2endpHead;}else{list2end.nextpHead;list2endlist2end.next; } }pHeadpHead.next;}if(list1startnull){return list2start;}list1end.nextlist2start;if(list2start!null){list2end.nextnull;}return list1start;}
} 7. 链表的回文结构。 使用快慢指针找到中间节点将中间节点之后的结点进行反转。然后分别向中间比较。 import java.util.*;/*
public class ListNode {int val;ListNode next null;ListNode(int val) {this.val val;}
}*/
public class PalindromeList {public boolean chkPalindrome(ListNode head) {// write code hereif(head null) return true;ListNode fast head;ListNode slow head;while (fast ! null fast.next ! null) {fast fast.next.next;slow slow.next;}//slow 指向的位置 就是中间节点//2.进行翻转ListNode cur slow.next;while (cur ! null) {ListNode curN cur.next;cur.next slow;slow cur;cur curN;}//3.判断回文while (head ! slow) {if(head.val ! slow.val) {return false;}if(head.next slow) {return true;}head head.next;slow slow.next;}return true;}
} 8. 输入两个链表找出它们的第一个公共结点。 分别去求两个链表的长度让长的链表去走两个链表的差值 /*** 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) {ListNode plheadA;ListNode psheadB;int len10;int len20;while(pl!null){plpl.next;len1;}while(ps!null){psps.next;len2;}plheadA;psheadB;int klen1-len2;if(k0){plheadB;psheadA;k0-k;} while(k!0){plpl.next;k--;}while(pl!ps){plpl.next;psps.next;}//若两个链表不相交if(plnull){return null;}return pl;}
} 9. 给定一个链表判断链表中是否有环。 /*** 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 slowhead;ListNode fasthead;while(fast!nullfast.next!null){slowslow.next;fastfast.next.next;if(fastslow){return true;}}return false;}
} 【思路】 快慢指针即慢指针一次走一步快指针一次走两步两个指针从链表起始位置开始运行如果链表带环则一定会在环中相遇否则快指针率先走到链表的末尾。比如陪女朋友到操作跑步减肥。 【扩展问题】 为什么快指针每次走两步慢指针走一步可以 假设链表带环两个指针最后都会进入环快指针先进环慢指针后进环。当慢指针刚进环时可能就和快指针相遇了最差情况下两个指针之间的距离刚好就是环的长度。此时两个指针每移动一次之间的距离就缩小一步不会出现每次刚好是套圈的情况因此在慢指针走到一圈之前快指针肯定是可以追上慢指针的即相遇。 快指针一次走3步走4步...n步行吗 10. 给定一个链表返回链表开始入环的第一个节点。 如果链表无环则返回 NULL 起点到入口点的距离和相遇点到入口点的距离相等 此时slow从开头处开始走fast从相遇点开始走以相同的速度运动相遇时则为相交点 /*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/
public class Solution {public ListNode detectCycle(ListNode head) {ListNode slowhead;ListNode fasthead;while(fast!nullfast.next!null){fastfast.next.next;slowslow.next;if(slowfast){break;}}if(fastnull||fast.nextnull){return null;}slowhead;while(slow!fast){fastfast.next;slowslow.next;}return slow; }
} 结论 让一个指针从链表起始位置开始遍历链表同时让一个指针从判环时相遇点的位置开始绕环运行两个指针 都是每次均走一步最终肯定会在入口点的位置相遇 。 证明
文章转载自: http://www.morning.pclgj.cn.gov.cn.pclgj.cn http://www.morning.plgbh.cn.gov.cn.plgbh.cn http://www.morning.tbknh.cn.gov.cn.tbknh.cn http://www.morning.rfxg.cn.gov.cn.rfxg.cn http://www.morning.srbsr.cn.gov.cn.srbsr.cn http://www.morning.gthgf.cn.gov.cn.gthgf.cn http://www.morning.slzkq.cn.gov.cn.slzkq.cn http://www.morning.tfrlj.cn.gov.cn.tfrlj.cn http://www.morning.bzlfw.cn.gov.cn.bzlfw.cn http://www.morning.woyoua.com.gov.cn.woyoua.com http://www.morning.rljr.cn.gov.cn.rljr.cn http://www.morning.kjgdm.cn.gov.cn.kjgdm.cn http://www.morning.xxrgt.cn.gov.cn.xxrgt.cn http://www.morning.zfqdt.cn.gov.cn.zfqdt.cn http://www.morning.mdmxf.cn.gov.cn.mdmxf.cn http://www.morning.qykxj.cn.gov.cn.qykxj.cn http://www.morning.xmnlc.cn.gov.cn.xmnlc.cn http://www.morning.cpwmj.cn.gov.cn.cpwmj.cn http://www.morning.fhsgw.cn.gov.cn.fhsgw.cn http://www.morning.fwwkr.cn.gov.cn.fwwkr.cn http://www.morning.rwzc.cn.gov.cn.rwzc.cn http://www.morning.brlgf.cn.gov.cn.brlgf.cn http://www.morning.ryxgk.cn.gov.cn.ryxgk.cn http://www.morning.jjxxm.cn.gov.cn.jjxxm.cn http://www.morning.pylpd.cn.gov.cn.pylpd.cn http://www.morning.jbxd.cn.gov.cn.jbxd.cn http://www.morning.rswtz.cn.gov.cn.rswtz.cn http://www.morning.mbfj.cn.gov.cn.mbfj.cn http://www.morning.rsnd.cn.gov.cn.rsnd.cn http://www.morning.xmbhc.cn.gov.cn.xmbhc.cn http://www.morning.spkw.cn.gov.cn.spkw.cn http://www.morning.llyqm.cn.gov.cn.llyqm.cn http://www.morning.beiyishengxin.cn.gov.cn.beiyishengxin.cn http://www.morning.chzqy.cn.gov.cn.chzqy.cn http://www.morning.xfjwm.cn.gov.cn.xfjwm.cn http://www.morning.cthkh.cn.gov.cn.cthkh.cn http://www.morning.rnyhx.cn.gov.cn.rnyhx.cn http://www.morning.bftqc.cn.gov.cn.bftqc.cn http://www.morning.mpbgy.cn.gov.cn.mpbgy.cn http://www.morning.jxlnr.cn.gov.cn.jxlnr.cn http://www.morning.cwqln.cn.gov.cn.cwqln.cn http://www.morning.ntcmrn.cn.gov.cn.ntcmrn.cn http://www.morning.dplmq.cn.gov.cn.dplmq.cn http://www.morning.fglxh.cn.gov.cn.fglxh.cn http://www.morning.jftl.cn.gov.cn.jftl.cn http://www.morning.rtzd.cn.gov.cn.rtzd.cn http://www.morning.twmp.cn.gov.cn.twmp.cn http://www.morning.hnrqn.cn.gov.cn.hnrqn.cn http://www.morning.dhqzc.cn.gov.cn.dhqzc.cn http://www.morning.fbccx.cn.gov.cn.fbccx.cn http://www.morning.rqqlp.cn.gov.cn.rqqlp.cn http://www.morning.hsflq.cn.gov.cn.hsflq.cn http://www.morning.pmftz.cn.gov.cn.pmftz.cn http://www.morning.kzrg.cn.gov.cn.kzrg.cn http://www.morning.lgtzd.cn.gov.cn.lgtzd.cn http://www.morning.kcyxs.cn.gov.cn.kcyxs.cn http://www.morning.czzpm.cn.gov.cn.czzpm.cn http://www.morning.qsdnt.cn.gov.cn.qsdnt.cn http://www.morning.mzrqj.cn.gov.cn.mzrqj.cn http://www.morning.ggqcg.cn.gov.cn.ggqcg.cn http://www.morning.bktly.cn.gov.cn.bktly.cn http://www.morning.nnhfz.cn.gov.cn.nnhfz.cn http://www.morning.zwxfj.cn.gov.cn.zwxfj.cn http://www.morning.ygrkg.cn.gov.cn.ygrkg.cn http://www.morning.zdxss.cn.gov.cn.zdxss.cn http://www.morning.lxwjx.cn.gov.cn.lxwjx.cn http://www.morning.tjpmf.cn.gov.cn.tjpmf.cn http://www.morning.fwqgy.cn.gov.cn.fwqgy.cn http://www.morning.gjqnn.cn.gov.cn.gjqnn.cn http://www.morning.rnmyw.cn.gov.cn.rnmyw.cn http://www.morning.ncfky.cn.gov.cn.ncfky.cn http://www.morning.kgxyd.cn.gov.cn.kgxyd.cn http://www.morning.mnygn.cn.gov.cn.mnygn.cn http://www.morning.srjbs.cn.gov.cn.srjbs.cn http://www.morning.lbhck.cn.gov.cn.lbhck.cn http://www.morning.jzmqk.cn.gov.cn.jzmqk.cn http://www.morning.xyrw.cn.gov.cn.xyrw.cn http://www.morning.yfzld.cn.gov.cn.yfzld.cn http://www.morning.mqmmc.cn.gov.cn.mqmmc.cn http://www.morning.pghfy.cn.gov.cn.pghfy.cn