• C语言之OJ刷题


    今天刷一下题

    刷的不多

    第一道

    链表的回文结构

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

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

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

    但怎么做呢?

    思路

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

    然后将后半段倒置

    进行比较

    相同返回true

    继续想一下

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

    奇数和偶数

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

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

    但没关系

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

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

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

    代码

    1. #include
    2. class PalindromeList {
    3. public:
    4. //快慢指针
    5. struct ListNode* middleNode(struct ListNode* head) {
    6. ListNode* fast,*slow;
    7. fast=slow=head;
    8. while(fast && fast->next)
    9. {
    10. fast=fast->next->next;
    11. slow=slow->next;
    12. }
    13. return slow;
    14. }
    15. //倒置
    16. struct ListNode* reverseList(struct ListNode* head){
    17. ListNode* n1,*n2,*n3;
    18. n1=NULL;
    19. n2=head;
    20. n3=head->next;
    21. while(n2)
    22. {
    23. n2->next = n1;
    24. //修改三个指针的位置
    25. n1 = n2;
    26. n2 = n3;
    27. if(n3)
    28. {
    29. n3 = n3->next;
    30. }
    31. }
    32. return n1;
    33. }
    34. bool chkPalindrome(ListNode* A) {
    35. // write code here
    36. struct ListNode* mid=middleNode(A);
    37. struct ListNode* rmid = reverseList(mid);
    38. while(mid&&rmid)
    39. {
    40. if(A->val != rmid->val)
    41. return false;
    42. A = A->next;
    43. rmid=rmid->next;
    44. }
    45. return true;
    46. }
    47. };

    第二题

     思路

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

    返回相等的交点

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

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

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

    代码

    1. struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    2. struct ListNode* curA = headA;
    3. struct ListNode* curB = headB;
    4. int lenA = 1;
    5. while(curA->next)
    6. {
    7. ++lenA;
    8. curA = curA->next;
    9. }
    10. int lenB = 1;
    11. while(curB->next)
    12. {
    13. ++lenB;
    14. curB = curB->next;
    15. }
    16. if(curA != curB)//不相交
    17. {
    18. return NULL;
    19. }
    20. int gap = abs(lenA - lenB);//abs函数是取绝对值
    21. struct ListNode* longList = headA;
    22. struct ListNode* shortList = headB;
    23. if(lenB > lenA)
    24. {
    25. longList = headB;
    26. shortList = headA;
    27. }
    28. //让长的先走gap步
    29. while(gap--)
    30. {
    31. longList = longList->next;
    32. }
    33. //在同时走,找交点
    34. while(longList != shortList)
    35. {
    36. longList = longList->next;
    37. shortList = shortList->next;
    38. }
    39. return longList;
    40. }

    第三题 

    思路

    既然知识点中有双指针

    我们就用双指针去做

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

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

    返回慢指针就可以了

    这个题还是比较简单的

    代码

    1. struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    2. // write code here
    3. struct ListNode*fast,*slow;
    4. fast = slow = pListHead;
    5. while(k--)
    6. {
    7. if(fast == NULL)
    8. {
    9. return NULL;
    10. }
    11. fast = fast->next;
    12. }
    13. while(fast)
    14. {
    15. fast = fast->next;
    16. slow = slow->next;
    17. }
    18. return slow;
    19. }

    第四题


    思路

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

    所以用循环的话很困难

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

    所以

    这道题我们用快慢指针

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

    代码

    1. struct ListNode *detectCycle(struct ListNode *head) {
    2. struct ListNode* fast,*slow;
    3. fast = slow = head;
    4. if(head == NULL)
    5. {
    6. return false;
    7. }
    8. while(fast && fast->next)
    9. {
    10. fast = fast->next->next;
    11. slow = slow->next;
    12. if(fast == slow)
    13. {
    14. struct ListNode* node1 = head;
    15. struct ListNode* node2 = fast;
    16. while(node1 != node2)
    17. {
    18. node1 = node1->next;
    19. node2 = node2->next;
    20. }
    21. return node2;
    22. }
    23. }
    24. return NULL;
    25. }

    第五题

    思路

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

    代码

    1. struct Node* copyRandomList(struct Node* head) {
    2. struct Node* cur = head;
    3. //拷贝节点插入源节点的后面
    4. while(cur)
    5. {
    6. struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
    7. copy->val = cur->val;
    8. //插入
    9. copy->next = cur->next;
    10. cur->next = copy;
    11. //迭代
    12. cur = cur->next->next;
    13. }
    14. //控制拷贝节点的randmo
    15. cur = head;
    16. while(cur)
    17. {
    18. struct Node* copy = cur->next;
    19. if(cur->random == NULL)
    20. {
    21. copy->random = NULL;
    22. }
    23. else
    24. {
    25. copy->random = cur->random->next;
    26. }
    27. //迭代
    28. cur = cur->next->next;
    29. }
    30. //把copy节点解下来,连接成新链表
    31. struct Node* copyhead = NULL,*tail = NULL;
    32. cur = head;
    33. while(cur)
    34. {
    35. struct Node* copy = cur->next;
    36. struct Node* next = copy->next;
    37. //尾插
    38. if(tail == NULL)
    39. {
    40. copyhead = tail = copy;
    41. }
    42. else
    43. {
    44. tail->next = copy;
    45. tail = tail->next;
    46. }
    47. cur->next = next;
    48. cur = next;
    49. }
    50. return copyhead;
    51. }

  • 相关阅读:
    C++ 用户学习 Python 的最佳方法
    计算机类论文辅导(SCI写作和投稿),毕设辅导,竞赛辅导,升学材料润色
    文件加密,数据防泄密软件
    Codeforces Round #804 (Div. 2)(A~D)
    Day31脚本编写规则,判断语句,循环语句与case
    Revit SDK 介绍:NewForm 新建体量
    【luogu P5056】【模板】插头dp(插头DP)(分类讨论)
    含文档+PPT+源码等]精品基于SpringCloud实现的商品服务系统-微服务毕业设计项目源码-分布式毕设项目[包运行成功]
    【无标题】
    Vue基础使用
  • 原文地址:https://blog.csdn.net/2301_80157147/article/details/136232339