classListNode{int val;ListNode next;ListNode(){}ListNode(int val){this.val=val;}}classMyLinkedList{//size存储链表元素的个数int size;//虚拟头结点ListNode head;//初始化链表publicMyLinkedList(){
size =0;
head =newListNode(0);}//获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点publicintget(int index){//如果index非法,返回-1if(index >= size){return-1;}ListNode currentNode = head;//包含一个虚拟头节点,所以查找第 index+1 个节点for(int i =0; i <= index; i++){
currentNode = currentNode.next;}return currentNode.val;}//在链表最前面插入一个节点,等价于在第0个元素前添加publicvoidaddAtHead(int val){addAtIndex(0, val);}//在链表的最后插入一个节点,等价于在(末尾+1)个元素前添加publicvoidaddAtTail(int val){addAtIndex(size, val);}// 在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。// 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点// 如果 index 大于链表的长度,则返回空publicvoidaddAtIndex(int index,int val){if(index > size){return;}//找到要插入节点的前驱ListNode pred = head;for(int i =0; i < index; i++){
pred = pred.next;}ListNode toAdd =newListNode(val);ListNode t = pred.next;
toAdd.next = t;
pred.next = toAdd;
size++;}//删除第index个节点publicvoiddeleteAtIndex(int index){if(index >= size){return;}
size--;if(index ==0){
head = head.next;return;}ListNode pred = head;for(int i =0; i < index ; i++){
pred = pred.next;}
pred.next = pred.next.next;}}
反转链表
1. 反转链表
太熟悉了
直接上代码:
classSolution{publicListNodereverseList(ListNode head){ListNode pre =null;ListNode cur = head;while(cur !=null){ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;}return pre;}}
2. 反转链表2
需要定位到反转目标段的前一个节点,因此需要添加哨兵节点
代码:
classSolution{publicListNodereverseBetween(ListNode head,int left,int right){ListNode dummy =newListNode(0, head), p0 = dummy;for(int i =0; i < left -1;++i)
p0 = p0.next;ListNode pre =null, cur = p0.next;ListNode p1 = p0.next;for(int i =0; i < right - left +1;++i){ListNode nxt = cur.next;
cur.next = pre;
pre = cur;
cur = nxt;}
p1.next = cur;
p0.next = pre;return dummy.next;}}
3. K个一组反转链表
核心就是要记录节点,并且每次循环都要更新dummy
代码:
classSolution{publicListNodereverseKGroup(ListNode head,int k){ListNode dummy =newListNode(0, head);ListNode p0 = dummy;intL=0;while(p0 !=null){
p0 = p0.next;L++;}L=L-1;
p0 = dummy;for(int i =L; i >= k; i-=k){ListNode pre =null;ListNode p1 = p0.next;ListNode cur = p0.next;for(int j =0; j < k; j++){ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;}
p1.next = cur;
p0.next = pre;
p0 = p1;}return dummy.next;}}
删除链表倒数第N个节点
核心就是添加dummy,定位到前一个节点
环形链表1
快慢指针
代码:
publicclassSolution{publicbooleanhasCycle(ListNode head){ListNode slow = head;ListNode fast = head;while(fast !=null&& fast.next !=null){
fast = fast.next.next;
slow = slow.next;if(slow == fast){returntrue;}}returnfalse;}}
环形链表2
核心就是head节点到环口的位置的距离是环的整数倍
代码:
classSolution{publicListNodedetectCycle(ListNode head){ListNode slow = head, fast = head;//快慢指针while(fast !=null&& fast.next !=null){
slow = slow.next;
fast = fast.next.next;if(fast == slow){//相遇while(slow != head){//满足head节点到环口的位置的距离是环的整数倍时,找到环口
slow = slow.next;
head = head.next;//fast = fast.next.next;}return slow;}}returnnull;}}