目录
LeetCode88.合并两个有序数组
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int point1=m-1,point2=n-1;
while(point1>=0 && point2>=0){
if(nums1[point1]>nums2[point2]){
nums1[point1+point2+1]=nums1[point1];
point1--;
}
else {
nums1[point1+point2+1]=nums2[point2];
point2--;
}
}
if(point2>=0){
for(int i=0;i<=point2;i++){
nums1[i]=nums2[i];
}
}
}
};
LeetCode203.移除链表元素
struct ListNode* removeElements(struct ListNode* head, int val) {
// 先处理头节点
while (head != NULL && head->val == val) {
struct ListNode* temp = head;
head = head->next;
free(temp);
}
// 如果链表已经为空,直接返回 NULL
if (head == NULL) {
return NULL;
}
// 处理非头节点的情况
struct ListNode* cur2 = head;
while (cur2->next != NULL) {
if (cur2->next->val == val) {
struct ListNode* temp = cur2->next;
cur2->next = cur2->next->next;
free(temp);
} else {
cur2 = cur2->next; // 只有不删除时才移动 cur2
}
}
return head;
}
LeetCode206. 反转链表
LeetCode206. 反转链表
分析:
方法一(迭代法)通过初始化三个指针,具体见上图
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
if(head==NULL)return NULL;
struct ListNode*node1,*node2,*node3;
node1=NULL;
node2=head;
node3=head->next;
while(node2){
//翻转
node2->next=node1;
//迭代
node1=node2;
node2=node3;
if(node3){
node3=node3->next;
}
}
return node1;
}
方法二(头插)
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode*cur=head;
struct ListNode*newhead=NULL;
while(cur){
struct ListNode*next=cur->next;
//头插
cur->next=newhead;
newhead=cur;
//迭代往后走
cur=next;
}
return newhead;
}
nowcoderJZ22 链表中倒数最后k个结点
牛客JZ22 链表中倒数最后k个结点
分析(双指针):
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
// write code here
struct ListNode*fast,*slow;
slow=pHead;
fast=pHead;
while(k--){
if(!fast)return NULL;
fast=fast->next;
}
while(fast!=NULL){
slow=slow->next;
fast=fast->next;
}
return slow;
}
Leetcode21.合并两个有序链表
Leetcode21.合并两个有序链表
刚开始试了试就插到list1里面去,但是比较麻烦
方法一(多定义一个指针cur,方便找尾)
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
//如果一个为空就返回另一个
if (list1 == NULL) return list2;
if (list2 == NULL) return list1;
struct ListNode*p1,*p2,*newhead,*cur;
p1=list1;
p2=list2;
newhead=NULL;
cur=NULL;
while(p1!=NULL&&p2!=NULL){
if(p1->val<=p2->val){
if(!newhead)newhead=p1;
if(cur)cur->next=p1;
cur=p1;
p1=p1->next;
}
else{
if(!newhead)newhead=p2;
if(cur)cur->next=p2;
cur=p2;
p2=p2->next;
}
}
//处理剩余
if(p1 != NULL) {
cur->next = p1;
}
if(p2 != NULL) {
cur->next = p2;
}
return newhead;
}
nowcoder链表分割
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
#include <cstdlib>
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
if(!pHead)return NULL;
// write code here
struct ListNode*cur,*lesshead,*greaterHead,*lessTail,*greaterTail;
//建立两个带头结点的链表
lesshead=(struct ListNode*)malloc(sizeof(struct ListNode));
greaterHead=(struct ListNode*)malloc(sizeof(struct ListNode));
lesshead->next=NULL;
greaterHead->next=NULL;
lessTail=lesshead;
greaterTail=greaterHead;
cur=pHead;
while(cur!=NULL){
if(cur->val<x){
lessTail->next=cur;
lessTail=lessTail->next;
}
else{
greaterTail->next=cur;
greaterTail=greaterTail->next;
}
cur=cur->next;
}
lessTail->next=greaterHead->next;
greaterTail->next=NULL;
struct ListNode* newHead=lesshead->next;
free(lesshead);
free(greaterHead);
lesshead=NULL;
greaterHead=NULL;
return newHead;
}
};
nowcoderOR36 链表的回文结构
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
//找中间节点
struct ListNode* middleNode(struct ListNode* head) {
if (!head) return NULL;
ListNode* slow = head;
ListNode* fast = head;
// 快指针走两步,慢指针走一步,直到快指针到达链表末尾
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow; // 慢指针指向链表中间节点
}
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* cur = head;
struct ListNode* newhead = NULL;
while (cur) {
struct ListNode* next = cur->next;
//头插
cur->next = newhead;
newhead = cur;
//向后迭代
cur = next;
}
return newhead;
}
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
if (!A || !A->next) return true; // 只有一个节点或空链表时
struct ListNode* mid = middleNode(A);
struct ListNode* rehead = reverseList(mid);
// 对比前半部分和后半部分
ListNode* cur1 = A;
ListNode* cur2 = rehead;
while (cur2) {
if (cur1->val != cur2->val) {
return false;
}
cur1 = cur1->next;
cur2 = cur2->next;
}
return true;
}
};
再补一个关于快慢指针找中间节点的
LeetCode160.相交链表
160.相交链表
先找尾,如果尾结点相同,则必相交(找尾同时记录一下节点个数),如果
c
o
u
n
t
A
>
c
o
u
n
t
B
countA>countB
countA>countB,则
c
u
r
A
curA
curA比
c
u
r
B
curB
curB先走
c
o
u
n
t
A
−
c
o
u
n
t
B
countA-countB
countA−countB步,反之同理,最后再开始向后遍历一个一个比较
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode*tailA=headA;
struct ListNode*tailB=headB;
int countA=0;
int countB=0;
while(tailA->next){
tailA=tailA->next;
countA++;
}
while(tailB->next){
tailB=tailB->next;
countB++;
}
//不相交
if(tailA!=tailB)return NULL;
//相交
struct ListNode*curA=headA;
struct ListNode*curB=headB;
while(countA!=countB){
if(countA>countB){
curA=curA->next;
countA--;
}
else if(countB>countA){
curB=curB->next;
countB--;
}
}
while(curA&&curB){
if(curA==curB) break;
curA=curA->next;
curB=curB->next;
}
return curA;
}
LeetCode141.环形链表Ⅰ
bool hasCycle(struct ListNode *head) {
struct ListNode*fast,*slow;
fast=head;
slow=head;
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
if(slow==fast){
return true;
}
}
return false;
}
LeetCode142.环形链表Ⅱ
142.环形链表Ⅱ
这种方法我反正想不出来
两个指针,一个从链表头head开始走,一个从相遇点meetnode开始走,在入口点相遇
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode*fast,*slow;
fast=head;
slow=head;
while(fast&&fast->next){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
struct ListNode*meetnode=fast;
while(head!=meetnode){
head=head->next;
meetnode=meetnode->next;
}
return head;
}
}
return NULL;
}
LeetCode138. 随机链表的复制
struct Node* copyRandomList(struct Node* head) {
if (head == NULL) {
return NULL; // 处理空链表的情况
}
struct Node* cur = head;
while (cur) {
// 1.copy节点插入原节点的后面
struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
copy->val = cur->val;
// 插入
copy->next = cur->next;
cur->next = copy;
// 向后迭代
cur = copy->next;
}
// 2.根据原节点的random处理copy节点的random
cur = head;
while (cur) {
struct Node* copy = cur->next;
if (!cur->random)
copy->random = NULL;
else
copy->random = cur->random->next;
cur = copy->next;
}
// 3.将复制节点解下来连成新链表,恢复原链表的链接关系
cur = head;
struct Node* copyhead =(struct Node*)malloc(sizeof(struct Node)); // 创建新链表的头节点
struct Node* copytail = copyhead; // copytail 用于迭代连接复制链表
while (cur) {
struct Node* copy = cur->next; // 获取复制节点
copytail->next = copy; // 连接到新链表
copytail = copy; // 更新copytail指针
cur->next = copy->next; // 恢复原链表
cur = cur->next; // 推进到下一个原链表节点
}
return copyhead->next; // 返回新链表的第一个有效节点
}