每日算法4/10

LCR 026. 重排链表https://leetcode.cn/problems/LGjMqU/

题目

给定一个单链表 L 的头节点 head ,单链表 L 表示为:

 L0 → L1 → … → Ln-1 → Ln 
请将其重新排列后变为:

L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → …

不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:

 

b3c7df76a5f077272900d85507b049b0.png

输入: head = [1,2,3,4]
输出: [1,4,2,3]

示例 2:

 

2f1273ef2c05386623caf91c4834065f.png

输入: head = [1,2,3,4,5]
输出: [1,5,2,4,3]

提示:

  • 链表的长度范围为 [1, 5 * 104]
  • 1 <= node.val <= 1000

方法一思路

  • 运用指针数组与头尾指针,实现从两端的逼近

方法一 代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode;
typedef ListNode *List;   //定义结构指针

void reorderList(struct ListNode* head){
    List p[50001];        //定义指针数组
    List h=head;
    int tail=0;           //尾指针
    while(h){
        a[tail++]=h;
        h=h->next;
    }                     //指针数组赋值
    tail--;               //tail由变为长度减一
    int n=0;              //头指针
    while(tail>n+1){
        a[tail]->next=a[n]->next;
        a[n]->next=a[tail];
        n++,tail--;
    }
    a[tail]->next=NULL;
}

方法二思路

  • 通过将后半段的链表节点进行头插法的逆转,相当于将要插入的节点存入另一个链表中
  • 然后两个链表从头遍历进行插入,需要一个临时节点保存下一个节点防止节点丢失

方法二 代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode;
void reorderList(struct ListNode* head) {
    int len = 0;
    ListNode* tail = head;
    while (tail) {
        len++;
        tail = tail->next;
    }
    if(len == 0||len==1)
        return;
    int mid = len / 2;
    ListNode* cur = head;
    for (int i = 0; i < len - mid; i++) {
        cur = cur->next;
    }
    ListNode* newhead = NULL;
    while (cur) {
        ListNode* temp = cur->next;
        cur->next = newhead;
        newhead = cur;
        cur = temp;
    }
    cur = head;
    ListNode* cur2 = newhead;
    for (int i = 0; i < len / 2; i++) {
        ListNode* temp = cur2->next;
        cur2->next = cur->next;
        cur->next = cur2;
        cur = cur2->next;
        cur2 = temp;
    }
    tail = head;
    for(int i = 0; i < len; i++){
        printf("%d",tail->val);
        tail = tail->next;
    }
    printf("%d",tail->next->val);
    tail->next->next = NULL;
}

LCR 027. 回文链表https://leetcode.cn/problems/aMhZSa/

题目

给定一个链表的 头节点 head ,请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

 

示例 1:

 

86c2fc6243e5f5f1c5b46c99ac237166.png

输入: head = [1,2,3,3,2,1]
输出: true

示例 2:

 

2568d9afe2bad292841f749a47be0b28.png

输入: head = [1,2]
输出: false

 

提示:

  • 链表 L 的长度范围为 [1, 105]
  • 0 <= node.val <= 9

 

思路 

  • 通过结构体指针数组,存放各个节点的地址,就能够实现从头往后,从后往前进行遍历比较
  • 如果对称位置的两个指向的值不相等那么不是回文链表,直到遍历完,都没遇到不相等的情况,那么这个链表即使回文的

代码 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

typedef struct ListNode ListNode;
bool isPalindrome(struct ListNode* head) {
    ListNode* Tail = head;
    int len = 0;
    while (Tail) {
        len++;
        Tail = Tail->next;
    }

    ListNode* p[100001];
    ListNode* h = head;
    int tail = 0;
    while (h) {
        p[tail++] = h;
        h = h->next;
    }
    int start = 0;
    tail--;
    while (start < tail) {
        if (p[tail]->val != p[start]->val)
            return false;
        start++;
        tail--;
    }
    return true;
}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值