坚持内卷,pua自己,不是你死,就是我活。
707. 设计链表
注意 在get 和add 和delete 写循环条件 是index 不是size
index就是要插入或删除的位置
class ListNode{
int val;
ListNode next;
ListNode (){}
ListNode( int val){
this.val = val;
}
}
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
public int get(int index) {
if(index <0 || index >=size) return -1;
ListNode cur = head;
for( int i = 0; i<=index; i++){
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(size,val);
}
public void addAtIndex(int index, int val) {
if(index >size) return;
if(index <0) index = 0;
ListNode cur = head;
for( int i = 0; i <index; i++)
cur = cur.next;
ListNode t = new ListNode(val);
t.next = cur.next;
cur.next = t;
size++;
}
public void deleteAtIndex(int index) {
if(index >=size || index <0) return;
ListNode cur = head;
for( int i = 0; i <index; i++)
cur = cur.next;
cur.next = cur.next.next;
size--;
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
203. 移除链表元素
/**
* 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 val) {
ListNode i = new ListNode(-1,head);
ListNode pre = i ;
ListNode t = head;
while(t !=null){
if(t.val == val){
pre.next = t.next;
}else{
pre = t;
}
t = t.next;
}
return i.next;
}
}
206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
法1:双指针法
/**
* 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) {
ListNode temp;
ListNode pre = null;
ListNode cur = head;
while(cur != null){
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
法2:递归法
递归法相对抽象一些,但是其实和双指针法是一样的逻辑,同样是当cur为空的时候循环结束,不断将cur指向pre的过程。
关键是初始化的地方,可能有的同学会不理解, 可以看到双指针法中初始化 cur = head,pre = NULL,在递归法中可以从如下代码看出初始化的逻辑也是一样的,只不过写法变了。
具体可以看代码(已经详细注释),双指针法写出来之后,理解如下递归写法就不难了,代码逻辑都是一样的。
24. 两两交换链表中的节点
递归解法
其中我们应该关心的主要有三点:
-
返回值
-
调用单元做了什么
-
终止条件
在本题中:
返回值:交换完成的子链表
调用单元:设需要交换的两个点为 head 和 next,head 连接后面交换完成的子链表,next 连接 head,完成交换
终止条件:head 为空指针或者 next 为空指针,也就是当前无节点或者只有一个节点,无法进行交换
/**
* 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 swapPairs(ListNode head) {
//终止条件
if(head ==null ||head.next == null)
return head;
ListNode next = head.next;
head.next = swapPairs(next.next);//返回完成交换的子列表
next.next = head;
return next;
}
}
非递归方法
/**
* 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 swapPairs(ListNode head) {
ListNode Ma = new ListNode(0);
Ma.next = head;
ListNode pre = Ma;
while(pre.next != null && pre.next.next != null){//&&而不是||
ListNode temp = head.next.next;
pre.next = head.next;
head.next.next = head;
head.next = temp;
pre= head;//将pre指针前进一步
head= head.next;
}
return Ma.next;
}
}
19. 删除链表的倒数第 N 个结点
目的:得到要删除的的结点前一个结点
双指针做法 , 让前后指针相隔n个结点,让两个指针循环下去,最后要删除的结点就是前一个结点,再得到删除结点的前一个结点,用temp.next = pre.next进行删除
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode follow = dummy;
ListNode pre =dummy;
for(int i = 0 ; i <n;i++){
follow = follow.next;
}
ListNode temp = null;
while(follow != null){
temp = pre;
follow = follow.next;
pre = pre.next;
}
temp.next= pre.next;
return dummy.next;
}
}