数据结构代码OJ练习1顺序表链表

LeetCode88.合并两个有序数组

88. LeetCode合并两个有序数组
在这里插入图片描述

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.移除链表元素

203.移除链表元素

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 链表的回文结构

OR36 链表的回文结构
在这里插入图片描述

/*
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 countAcountB步,反之同理,最后再开始向后遍历一个一个比较

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.环形链表Ⅰ

141.环形链表
在这里插入图片描述

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. 随机链表的复制

138. 随机链表的复制
在这里插入图片描述


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; // 返回新链表的第一个有效节点
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值