算法60天训练–9-8-day3
文章目录
(画图有些不规范)
203. 移除链表元素
思路
首先删除一个链表元素,无非就是将要删除的链表结点的上一个结点指向这个被删除链表的下一个结点
这里在刚开始将cur = dummy_head
,是为了将删除头结点的操作和其他结点的操作统一
即永远操作的结点都为cur->next
直到为空,在这个过程中找到要被删除的结点,执行删除操作
复杂度
- 时间复杂度: O(n)
- 空间复杂度: O(1)
Code(JAVA)
/**
* 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 dummy_Node = new ListNode(0);
dummy_Node.next = head;
ListNode cur = dummy_Node;
while(cur.next != null){
if(cur.next.val == val)
cur.next = cur.next.next;
else cur = cur.next;
}
return dummy_Node.next;
}
}
707. 设计链表
思路
这是一个比较综合的题目
get(int index)
这个跟其他链表元素有区别,将cur = d ummyhead->next
是为了解决index等于0的情况,避免没有进入while循环而造成直接返回return cur->val;
addAtHead
在 链表头插入时要注意顺序问题
addAtTail
直接在结尾插入即可
addAtIndex
还是注意插入的顺序问题
deleteAtIndex
找到要删除的结点,将该结点的上一个结点指向下一个结点
时间复杂度
时间复杂度: 涉及 index 的相关操作为 O(index), 其余为 O(1)
空间复杂度: O(n)
Code(C++)
class MyLinkedList {
public:
struct ListNode{
int val;
ListNode* next;
ListNode(int val):val(val),next(nullptr){}
};
MyLinkedList() {
dummy_head = new ListNode(0);
_size = 0;
}
int get(int index) {
if(index > (_size-1) || index < 0){
return -1;
}
ListNode* cur = dummy_head->next;//要在虚拟头节点的下一个结点,以解决index等于0的情况
while(index--){
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
ListNode* newNode = new ListNode(val);
newNode->next = dummy_head->next;
dummy_head->next = newNode;
_size++;
}
void addAtTail(int val) {
ListNode* cur = dummy_head;
ListNode* newNode = new ListNode(val);
while(cur->next != nullptr){
cur = cur->next;
}
cur->next = newNode;
_size++;
}
void addAtIndex(int index, int val) {
ListNode* newNode = new ListNode(val);
ListNode* cur = dummy_head;
if(index > _size) return;
while(index--){
cur = cur->next;
}
newNode->next = cur->next;//要保证操作的节点是cur->next;
cur->next = newNode;
_size++;
}
void deleteAtIndex(int index) {
if (index > _size-1 || index < 0) {
return;
}
// 要保证第n个结点一定要是cur->next;
ListNode* cur = dummy_head;
ListNode* temp = NULL;
while(index--){
cur = cur->next;
}
temp = cur->next;
cur->next = cur->next->next;
delete temp;
temp = nullptr;
_size--;
}
private:
int _size;
ListNode* dummy_head;
};
/**
* 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);
*/
206. 反转链表
思路
定义一个temp,来临时存放cur->next,这样在cur->next = pre之后,才能将cur = temp到下一个结点去
Code(JAVA)
/**
* 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 pre = null;
ListNode cur = head;
ListNode temp = new ListNode();
while(cur != null){
temp = cur.next; //因为如果将cur指向pre后就无法找到cur的下一个节点了
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}