C语言之OJ刷题

今天刷一下题

刷的不多

第一道

链表的回文结构

仔细看这个题它是有限制条件的

首先是时间复杂度和空间复杂度

所以我们并不是用数组去做

但怎么做呢?

思路

既然是判断是否是回文结构,那么我们就找一下他的中间节点

然后将后半段倒置

进行比较

相同返回true

继续想一下

找中间节点的话有两种情况

奇数和偶数

所以我们使用快慢指针的方法去找寻中间节点

但是如果是奇数的话,翻转过来会发现不一样了

但没关系

因为如果是1->2->3->2->1

这样翻转过来就相当于1->2->3-<2-<1

这样是一对一,二对二,而三自己比

代码

cpp 复制代码
#include <cstddef>
class PalindromeList {
  public:

    //快慢指针
    struct ListNode* middleNode(struct ListNode* head) {
       ListNode* fast,*slow;
       fast=slow=head;
       while(fast && fast->next)
       {
        fast=fast->next->next;
        slow=slow->next;
       }
       return slow;
    }
    //倒置
    struct ListNode* reverseList(struct ListNode* head){
        ListNode* n1,*n2,*n3;
        n1=NULL;
        n2=head;
        n3=head->next;
        while(n2)
        {
             n2->next = n1;
        //修改三个指针的位置
        n1 = n2;
        n2 = n3;
        if(n3)
          {
            n3 = n3->next;
          }
        }
        return n1;
        }


    bool chkPalindrome(ListNode* A) {
        // write code here
        struct ListNode* mid=middleNode(A);
        struct ListNode* rmid = reverseList(mid);

        while(mid&&rmid)
        {
            if(A->val != rmid->val)
            return false;
            A = A->next;
            rmid=rmid->next;
        }
        return true;
    }
    
};

第二题

思路

第一个思路就是不断地让a链表和b链表的节点进行一一比较

返回相等的交点

时间复杂度是O(N^2)

第二个思路呢就是长链表先把差走完,然后两个链表走后看一看是否节点的next一致,一致就返回该节点

这里对比的是节点不是节点值

代码

cpp 复制代码
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* curA = headA;
    struct ListNode* curB = headB;
    int lenA = 1;
    while(curA->next)
    {
        ++lenA;
        curA = curA->next;
    }
    int lenB = 1;
    while(curB->next)
    {
        ++lenB;
        curB = curB->next;
    }

    if(curA != curB)//不相交
    {
        return NULL;
    }

     int gap = abs(lenA - lenB);//abs函数是取绝对值
    struct ListNode* longList = headA;
    struct ListNode* shortList = headB;
     if(lenB > lenA)
     {
        longList = headB;
        shortList = headA;

     }
     //让长的先走gap步
     while(gap--)
     {
         longList = longList->next;
     }
     //在同时走,找交点
     while(longList != shortList)
     {
         longList = longList->next;
         shortList = shortList->next;
     }
     return longList;


}

第三题

思路

既然知识点中有双指针

我们就用双指针去做

两个指针,一个快一个慢,快的先走k步

这样到最后快的走完慢的也就到了倒数第k个指针的位置了

返回慢指针就可以了

这个题还是比较简单的

代码

复制代码
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    // write code here
    struct ListNode*fast,*slow;
    fast = slow = pListHead;
    while(k--)
    {
        if(fast == NULL)
        {
            return NULL;
        }
        fast = fast->next;
    }
    while(fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return slow;

}

第四题

思路

像这个题,麻烦的点是我们不知道他什么时候进环

所以用循环的话很困难

用数组的话我们不知道数组多大也有点麻烦

所以

这道题我们用快慢指针

先确定有环,在确定进环的位置

代码

cpp 复制代码
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* fast,*slow;
    fast = slow = head;
    if(head == NULL)
    {
        return false;
    }
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        {
            struct ListNode* node1 = head;
            struct ListNode* node2 = fast;
            while(node1 != node2)
            {
                node1 = node1->next;
                node2 = node2->next;
            }
            return node2;
        }
    }
    return NULL;
}

第五题

思路

这里我们需要创造节点去拷贝

代码

cpp 复制代码
struct Node* copyRandomList(struct Node* head) {
	struct Node* cur = head;
    //拷贝节点插入源节点的后面
    while(cur)
    {
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;

        //插入
        copy->next = cur->next;
        cur->next = copy;

        //迭代
        cur = cur->next->next; 
    }

    //控制拷贝节点的randmo
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }

        //迭代
        cur = cur->next->next;
    }

    //把copy节点解下来,连接成新链表
    struct Node* copyhead = NULL,*tail = NULL;
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;

        //尾插
        if(tail == NULL)
        {
            copyhead = tail = copy;

        }
        else
        {

            tail->next = copy;
            tail = tail->next;
        }

        cur->next = next;
        cur = next;
    }
    return copyhead;
}
相关推荐
QuantumStack2 分钟前
【C++ 真题】P1104 生日
开发语言·c++·算法
whoarethenext18 分钟前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
代码的奴隶(艾伦·耶格尔)1 小时前
后端快捷代码
java·开发语言
Jay_5151 小时前
C++多态与虚函数详解:从入门到精通
开发语言·c++
路来了1 小时前
Python小工具之PDF合并
开发语言·windows·python
杰克尼2 小时前
BM5 合并k个已排序的链表
数据结构·算法·链表
xiaolang_8616_wjl2 小时前
c++文字游戏_闯关打怪
开发语言·数据结构·c++·算法·c++20
WJ.Polar2 小时前
Python数据容器-list和tuple
开发语言·python
small_wh1te_coder2 小时前
硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
linux·c语言·汇编·嵌入式硬件·算法·c
FrostedLotus·霜莲3 小时前
C++主流编辑器特点比较
开发语言·c++·编辑器