🛸~~ 🚁🚁🚁🛩️🛩️🛩️|

n1ce2cv

园龄:5年2个月粉丝:4关注:1

链表简单题

链表简单题

面试题 02.03. 删除中间节点

void deleteNode(struct ListNode *node) {
// 转换成删除下一个节点
node->val = node->next->val;
node->next = node->next->next;
}

1290. 二进制链表转整数

int getDecimalValue(struct ListNode *head) {
struct ListNode *cur = head;
int res = 0;
while (cur != NULL) {
res <<= 1;
res += cur->val;
cur = cur->next;
}
return res;
}

面试题 02.02. 返回倒数第 k 个节点

int kthToLast(struct ListNode *head, int k) {
struct ListNode *fast = head;
struct ListNode *slow = head;
// 快指针先走k步
while (k > 0) {
fast = fast->next;
k--;
}
// 快慢指针同时走
while (fast != NULL) {
fast = fast->next;
slow = slow->next;
}
return slow->val;
}

LCR 024. 反转链表

// 迭代
struct ListNode *reverseList(struct ListNode *head) {
struct ListNode *pre = NULL;
struct ListNode *next;
struct ListNode *cur = head;
// 原地反转
while (cur != NULL) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
// 递归
struct ListNode *reverseList(struct ListNode *head) {
// 递归出口
if (head == NULL || head->next == NULL) return head;
// 递归式
struct ListNode *newHead = reverseList(head->next); // 递归反转后面的链表
head->next->next = head; // 下个结点也就是反转后的尾节点,指向自己
head->next = NULL; // 自己作为新的尾节点
return newHead;
}

876. 链表的中间结点

// 返回向上取整的中间节点
struct ListNode *middleNode(struct ListNode *head) {
struct ListNode *fast = head;
struct ListNode *slow = head;
// 慢指针每走一步,快指针走两步
while (fast != NULL && fast->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}

LCR 023. 相交链表

// 返回两个单链表相交的起始节点
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
int len1 = 0, len2 = 0;
struct ListNode *p = headA, *q = headB;
// 求长度
while (p != NULL) {
len1++;
p = p->next;
}
while (q != NULL) {
len2++;
q = q->next;
}
// 长链表先走
p = headA;
q = headB;
if (len1 > len2)
for (int i = 0; i < len1 ### len2; ++i)
p = p->next;
else
for (int i = 0; i < len2 ### len1; ++i)
q = q->next;
// p、q距离尾节点距离相同时,同时出发
while (p != NULL) {
if (p == q)return p;
p = p->next;
q = q->next;
}
return NULL;
}

面试题 02.01. 移除重复节点

// 散列
struct ListNode *removeDuplicateNodes(struct ListNode *head) {
if (head == NULL || head->next == NULL) return head; // 特殊情况单独处理
int hash[20001]; // 记录是否出现过
memset(hash, 0, sizeof(hash));
struct ListNode *p = head;
hash[head->val] = 1;
// 判断当前下个节点是否需要删除
while (p != NULL && p->next != NULL) {
if (hash[p->next->val] == 0) {
// 首次出现
hash[p->next->val] = 1;
// 指针后移
p = p->next;
} else {
// 删除已经出现过
p->next = p->next->next;
// 指针无需后移
}
}
return head;
}
// 不使用散列
// 删除链表中所有值为k的节点
struct ListNode *removeNode(struct ListNode *head, int k) {
struct ListNode *headNode = (struct ListNode *) malloc(sizeof(struct ListNode));
headNode->next = head;
struct ListNode *p = headNode;
while (p != NULL && p->next != NULL) {
if (p->next->val == k) {
// 跳过节点
p->next = p->next->next;
// 指针无需后移
} else {
// 指针后移
p = p->next;
}
}
return headNode->next;
}
struct ListNode *removeDuplicateNodes(struct ListNode *head) {
if (head == NULL || head->next == NULL) return head; // 特殊情况单独处理
struct ListNode *cur = head;
while (cur != NULL && cur->next != NULL) {
// 删除后续链表中和当前值相同的所有节点
cur->next = removeNode(cur->next, cur->val);
cur = cur->next;
}
return head;
}

21. 合并两个有序链表

// 合并升序链表(迭代)
struct ListNode *mergeTwoLists(struct ListNode *list1, struct ListNode *list2) {
struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode));
head->next = NULL; // 写完成,不然if (list1 != NULL)会报错
struct ListNode *p = head;
// 从两个链表中反复选出较小者
while (list1 != NULL && list2 != NULL) {
if (list1->val < list2->val) {
p->next = list1;
list1 = list1->next;
} else {
p->next = list2;
list2 = list2->next;
}
p = p->next;
}
// 把剩余的链表直接接上
if (list1 != NULL) p->next = list1;
if (list2 != NULL) p->next = list2;
return head->next;
}
// 递归
struct ListNode *mergeTwoLists(struct ListNode *list1, struct ListNode *list2) {
// 递归出口
if (list1 == NULL) return list2;
if (list2 == NULL) return list1;
// 递归体
if (list1->val < list2->val) {
list1->next = mergeTwoLists(list1->next, list2);
return list1;
} else {
list2->next = mergeTwoLists(list1, list2->next);
return list2;
}
}

LCR 027. 回文链表

// 返回向上取整的中间节点
struct ListNode *findMid(struct ListNode *head) {
struct ListNode *slow = head;
struct ListNode *fast = head;
while (fast != NULL && fast->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
// 原地反转
struct ListNode *reverseList(struct ListNode *head) {
struct ListNode *pre = NULL;
struct ListNode *cur = head;
struct ListNode *next;
while (cur != NULL) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
bool isPalindrome(struct ListNode *head) {
struct ListNode *mid = findMid(head);
mid = reverseList(mid);
struct ListNode *p = head;
struct ListNode *q = mid;
while (q != NULL) {
if (p->val != q->val) return false;
p = p->next;
q = q->next;
}
return true;
}

203. 移除链表元素

// 删除链表中所有值为k的节点
struct ListNode *removeElements(struct ListNode *head, int val) {
struct ListNode *headNode = (struct ListNode *) malloc(sizeof(struct ListNode));
headNode->next = head;
struct ListNode *p = headNode;
while (p != NULL && p->next != NULL) {
if (p->next->val == val) {
// 跳过节点
p->next = p->next->next;
// 指针无需后移
} else {
// 指针后移
p = p->next;
}
}
return headNode->next;
}

83. 删除排序链表中的重复元素

struct ListNode *deleteDuplicates(struct ListNode *head) {
if (head == NULL || head->next == NULL) return head;
struct ListNode *dummyHead = (struct ListNode *) malloc(sizeof(struct ListNode));
dummyHead->next = head;
struct ListNode *cur = head;
while (cur != NULL) {
while (cur->next != NULL && cur->val == cur->next->val) {
// 跳过重复节点
cur->next = cur->next->next;
}
cur = cur->next;
}
return dummyHead->next;
}

141. 环形链表

bool hasCycle(struct ListNode *head) {
if (head == NULL || head->next == NULL) return false;
struct ListNode *slow = head;
struct ListNode *fast = head->next;
// 快慢指针,若有环,快指针迟早会追过慢指针(多跑了一个环的距离)
while (fast != NULL && fast->next != NULL) {
if (slow == fast)return true;
slow = slow->next;
fast = fast->next->next;
}
return false;
}

本文作者:n1ce2cv

本文链接:https://www.cnblogs.com/sprinining/p/17070230.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   n1ce2cv  阅读(38)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起