day3
1、链表理论基础
-
链表是以节点的方式来存储的【链式存储】
-
每个节点包括data域(存放数据)、指针域(next域、prev域)
- next域:指向下一个节点
- 最后一个节点的next域为null
- prev域:指向上一个节点
- 第一个节点的prev域为null
- next域:指向下一个节点
-
链表 VS 数组
- 链表的各个节点在内存中不一定是连续存储;数组在内存中连续存储
- 性能比较
![链表-链表与数据性能对比]()
2、leetcode203 移除链表元素
-
注意:
- 创建dummyHead虚拟头节点,作用:表示单链表的头【虚拟头节点不可移动】,指向链表的第一个节点。
- 通过一个辅助节点temp,帮助遍历整个链表。
- 删除节点时,辅助节点temp定位需删除节点的前一个节点 。
-
代码实现
class Solution { public ListNode removeElements(ListNode head, int val) { ListNode dummyHead = new ListNode(0); dummyHead.next = head; ListNode temp = dummyHead; while(temp.next != null){ if(temp.next.val == val){ temp.next = temp.next.next; } else { temp = temp.next; } } return dummyHead.next; } }
3、leetcode707 设计链表
class MyLinkedList {
Node dummyHead;
int size;
public MyLinkedList() {
dummyHead = new Node(0);
size = 0;
}
public int get(int index) {
if(index < 0 || index >= size){
return -1;
}
Node temp = dummyHead.next;
for(int i=0; i<index; i++){
temp = temp.next;
}
return temp.val;
}
public void addAtHead(int val) {
Node addNode = new Node(val);
addNode.next = dummyHead.next;
dummyHead.next = addNode;
size++;
}
public void addAtTail(int val) {
Node addNode = new Node(val);
Node temp = dummyHead;
while(temp.next != null){
temp = temp.next;
}
temp.next = addNode;
size++;
}
public void addAtIndex(int index, int val) {
if(index > size){
return;
}
Node temp = dummyHead;//定位要添加节点的前一个节点
Node addNode = new Node(val);
while(index > 0 ){
temp = temp.next;
index--;
}
addNode.next = temp.next;
temp.next = addNode;
size++;
}
public void deleteAtIndex(int index) {
if(index < 0 || index >= size){
return;
}
Node temp = dummyHead; //定位要删除节点的前一个节点
while(index>0){
temp = temp.next;
index--;
}
temp.next = temp.next.next;
size--;
}
}
class Node{
int val;
Node next;
public Node(int val){
this.val = val;
}
}
/**
* 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);
*/
4、leetcode206 反转链表
-
步骤
-
先定义一个新的头节点resverHead,作为翻转后的链表的头
-
从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表的最前端
-
-
代码实现
class Solution { public ListNode reverseList(ListNode head) { ListNode temp = head; //用于遍历原链表的辅助变量 ListNode tempNext = null; //用于记录temp节点的下一个节点 ListNode reverseHead = new ListNode(0); //新的头节点 while(temp != null){ tempNext = temp.next;//每次插入节点操作前,先记录下原链表中当前节点的下一个节点,防止插入操作后temp.next的指向发生改变,无法继续对原链表进行遍历 //每次都从头节点后面开始插入节点 temp.next = reverseHead.next; reverseHead.next = temp; temp = tempNext;//遍历原链表中的下一个节点,以便插入下一个节点 } return reverseHead.next; } }


浙公网安备 33010602011771号