203移除链表元素
使用原来的链表来进行移除节点
关键点在于对头节点的处理
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while(head!=NULL && head->val == val) {
ListNode* temp = head;
head = head->next;
delete temp;
}
ListNode *cur = head;
while(cur!=NULL && cur->next!=NULL) {
if(cur->next->val == val) {
ListNode* temp = cur->next;
cur -> next = cur->next->next;
delete temp;
}else {
cur = cur->next;
}
}
return head;
}
};
使用虚拟节点当作头节点
思路就是自己造一个虚拟节点避免掉要再考虑头节点的值=target值的特殊情况
class Solution2 {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode vir(val+1,head);
ListNode* cur = &vir;
while(cur!=NULL && cur->next!=NULL) {
if(cur->next->val == val) {
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp;
}else {
cur = cur->next;
}
}
return vir.next;
}
};
707设计链表
class MyLinkedList {
public:
struct Linked_node {
int val;
Linked_node* next;
Linked_node(int x,Linked_node* next):val(x),next(next){};
Linked_node(int x):val(x),next(NULL){};
};
MyLinkedList() {
_dummyHead = new Linked_node(0);
_size = 0;
}
int get(int index) {
if(index>0 && index<_size) {
Linked_node* temp = _dummyHead->next;
for(int i=0;i<index;i++) {
temp = temp->next;
}
return temp->val;
}
else return -1;
}
void addAtHead(int val) {
Linked_node* temp = new Linked_node(val,_dummyHead->next);
_dummyHead->next = temp;
_size ++;
}
void addAtTail(int val) {
Linked_node * temp = new Linked_node(val,NULL);
Linked_node * cur = _dummyHead;
while(cur->next != NULL) {
cur = cur->next;
}
cur->next = temp;
_size++;
}
void addAtIndex(int index, int val) {
if(index>_size) return;
if(index<0) index = 0;
Linked_node *temp = new Linked_node(val);
Linked_node *cur = _dummyHead;
for(int i=0;i<index;i++) {
cur = cur->next;
}
temp->next = cur->next;
cur->next = temp;
_size++;
}
void deleteAtIndex(int index) {
Linked_node* cur = _dummyHead;
for(int i=0;i<index;i++) {
cur = cur->next;
}
Linked_node* temp = cur->next;
cur->next = cur->next->next;
delete temp;
_size--;
}
private:
int _size;
Linked_node* _dummyHead;
};
206反转链表
双指针
//双指针法
ListNode* reverseList(ListNode* head) {
ListNode *pre = NULL;
ListNode *cur = head;
ListNode *temp ;
while(cur) {
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return cur;
}
递归法
ListNode *reverse(ListNode* cur,ListNode* pre){
if(cur == NULL) return pre;
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
return reverse(cur,pre);
}
ListNode *reverseList1(ListNode* head) {
return reverse(head,NULL);
}
24两两交换链表中的元素
虚拟头节点(画图就懂)
ListNode* swapPairs(ListNode* head) {
ListNode *dummy_node = new ListNode(0,head);
ListNode *cur = dummy_node;
ListNode* temp;
ListNode* temp1;
while(cur->next!=NULL && cur->next->next!=NULL) {
temp = cur->next;
temp1 =cur->next->next->next;
cur->next = cur->next->next;
cur -> next->next = temp;
temp->next = temp1;
cur = cur->next->next;
}
ListNode *result = dummy_node->next;
return result;
};
19删除链表的倒数的第N个节点
双链表法
//双指针
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead = new ListNode(0,head);
ListNode* fastIndex = dummyhead;
for(int i=0;i<n;i++) {
fastIndex = fastIndex->next;
}
if (fastIndex==NULL)
return dummyhead->next;
ListNode* slowindex = dummyhead;
while(fastIndex->next!=NULL) {
fastIndex = fastIndex->next;
slowindex = slowindex->next;
}
delete slowindex->next;
slowindex->next = slowindex->next->next;
return dummyhead->next;
}
面试题02.07链表相交
列表尾部对齐
//列表尾部对齐 我的写法
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA==NULL||headB==NULL)return NULL;
ListNode* a=headA;
ListNode* b=headB;
ListNode* slowIndex;
ListNode* shortNode;
while(a->next!=NULL && b->next!=NULL) {
a = a->next;
b = b->next;
}
if(a->next == NULL) {
shortNode = headA;
slowIndex = headB;
if(b->next != NULL) {
while(b->next!=NULL) {
b = b->next;
slowIndex = slowIndex->next;
}
}
}else {
shortNode = headB;
slowIndex = headA;
if(a->next != NULL) {
while(a->next!=NULL) {
a = a->next;
slowIndex = slowIndex->next;
}
}
}
while(slowIndex!=NULL ) {
if(slowIndex == shortNode) {
return slowIndex;
}else {
slowIndex = slowIndex->next;
shortNode = shortNode->next;
}
}
return NULL;
}
142环形链表
这个题解题思路还是挺有意思的用双指针,快指针一次走两格,慢指针一次走一格。这个的证明用举例子就行,他们两个再相遇之前的几种情况举出来就行。然后根据下面这幅图可以列出两个指针时间相等的式子,化简得到这里n必是大于等于1的逻辑思考一下就知道了。根据得出来的式子可以知道,让一个指针位于起点一个指针位于相遇点,以每次一格的速度往前走,最后会在环形入口节点相遇。
ListNode *detectCycle(ListNode *head) {
if(head == NULL)return NULL;
ListNode *fastP = head;
ListNode *slowP = head;
while(true) {
if(fastP->next==NULL || fastP->next->next==NULL){return NULL;}
else {
fastP = fastP->next->next;
slowP = slowP->next;
}
if(fastP == slowP) break;
}
slowP = head;
while(slowP!=fastP) {
fastP = fastP->next;
slowP = slowP->next;
}
return slowP;
}