2022-6-12 奇偶链表,分隔链表,链表组件,设计循环队列,查找和替换模式

1. 奇偶链表

Given the head of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return the reordered list.

The first node is considered odd, and the second node is even, and so on.

Note that the relative order inside both the even and odd groups should remain as it was in the input.

You must solve the problem in O(1) extra space complexity and O(n) time complexity.

Example 1

img

Input: head = [1,2,3,4,5]
Output: [1,3,5,2,4]

Example 2

img

Input: head = [2,1,3,5,6,4,7]
Output: [2,3,6,7,1,5,4]

Constraints:

  • The number of nodes in the linked list is in the range [0, 10^4].
  • -10^6 <= Node.val <= 10^6

代码

ListNode *oddEvenList(ListNode *head) {
    if (!head || !head->next) return head;
    auto head1 = head, head2 = head->next;
    auto node1 = head1, node2 = head2;
    while (node2 && node2->next) {
        node1->next = node2->next;
        node2->next = node2->next->next;
        node1 = node1->next;
        node2 = node2->next;
    }
    node1->next = head2;
    return head1;
}

2. 分隔链表

Given the head of a singly linked list and an integer k, split the linked list into k consecutive linked list parts.

The length of each part should be as equal as possible: no two parts should have a size differing by more than one. This may lead to some parts being null.

The parts should be in the order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal to parts occurring later.

Return an array of the k parts.

Example 1

Input: head = [1,2,3], k = 5
Output: [[1],[2],[3],[],[]]
Explanation:
The first element output[0] has output[0].val = 1, output[0].next = null.
The last element output[4] is null, but its string representation as a ListNode is [].

Example 2

Input: head = [1,2,3,4,5,6,7,8,9,10], k = 3
Output: [[1,2,3,4],[5,6,7],[8,9,10]]
Explanation:
The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.

Constraints:

  • The number of nodes in the list is in the range [0, 1000].
  • 0 <= Node.val <= 1000
  • 1 <= k <= 50

代码

vector<ListNode *> splitListToParts(ListNode *head, int k) {
    ListNode *node = head, *node2;
    int length = 0;
    while (node) ++length, node = node->next;
    int len = length / k, res = length % k;
    node = head;
    vector<ListNode *> result(k, nullptr);
    for (int i = 0; i < k && node; ++i) {
        result[i] = node;
        int n = len + (i < res) - 1;
        while (n--) node = node->next;
        node2 = node->next;
        node->next = nullptr;
        node = node2;
    }
    return result;
}

3. 链表组件

You are given the head of a linked list containing unique integer values and an integer array nums that is a subset of the linked list values.

Return the number of connected components in nums where two values are connected if they appear consecutively in the linked list.

Example 1

Input: head = [0,1,2,3], nums = [0,1,3]
Output: 2
Explanation: 0 and 1 are connected, so [0, 1] and [3] are the two connected components.

Example 2

Input: head = [0,1,2,3,4], nums = [0,3,1,4]
Output: 2
Explanation: 0 and 1 are connected, 3 and 4 are connected, so [0, 1] and [3, 4] are the two connected components.

Constraints:

  • The number of nodes in the linked list is n.
  • 1 <= n <= 10^4
  • 0 <= Node.val < n
  • All the values Node.val are unique.
  • 1 <= nums.length <= n
  • 0 <= nums[i] < n
  • All the values of nums are unique.

代码

int numComponents(ListNode *head, vector<int> &nums) {
    bitset<1 << 14> val;
    for (int x:nums) val.set(x);
    int result = 0;
    while (head) {
        while (head && !val.test(head->val)) head = head->next;
        if (head) result++;
        while (head && val.test(head->val)) head = head->next;
    }
    return result;
}

4. 设计循环队列

Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and the last position is connected back to the first position to make a circle. It is also called “Ring Buffer”.

One of the benefits of the circular queue is that we can make use of the spaces in front of the queue. In a normal queue, once the queue becomes full, we cannot insert the next element even if there is a space in front of the queue. But using the circular queue, we can use the space to store new values.

Implementation the MyCircularQueue class:

  • MyCircularQueue(k) Initializes the object with the size of the queue to be k.
  • int Front() Gets the front item from the queue. If the queue is empty, return -1.
  • int Rear() Gets the last item from the queue. If the queue is empty, return -1.
  • boolean enQueue(int value) Inserts an element into the circular queue. Return true if the operation is successful.
  • boolean deQueue() Deletes an element from the circular queue. Return true if the operation is successful.
  • boolean isEmpty() Checks whether the circular queue is empty or not.
  • boolean isFull() Checks whether the circular queue is full or not.

You must solve the problem without using the built-in queue data structure in your programming language.

Example 1

Input
["MyCircularQueue", "enQueue", "enQueue", "enQueue", "enQueue", "Rear", "isFull", "deQueue", "enQueue", "Rear"]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
Output
[null, true, true, true, false, 3, true, true, true, 4]

Explanation
MyCircularQueue myCircularQueue = new MyCircularQueue(3);
myCircularQueue.enQueue(1); // return True
myCircularQueue.enQueue(2); // return True
myCircularQueue.enQueue(3); // return True
myCircularQueue.enQueue(4); // return False
myCircularQueue.Rear();     // return 3
myCircularQueue.isFull();   // return True
myCircularQueue.deQueue();  // return True
myCircularQueue.enQueue(4); // return True
myCircularQueue.Rear();     // return 4

Constraints:

  • 1 <= k <= 1000
  • 0 <= value <= 1000
  • At most 3000 calls will be made to enQueue, deQueue, Front, Rear, isEmpty, and isFull.

代码

class MyCircularQueue {
private:
    int size, capacity;
    ListNode *front, *rear;

public:
    MyCircularQueue(int k) : size(0), capacity(k), front(nullptr), rear(nullptr) {}

    bool enQueue(int value) {
        if (isFull()) return false;
        if (isEmpty()) {
            front = rear = new ListNode(value);
        } else {
            rear->next = new ListNode(value);
            rear = rear->next;
        }
        ++size;
        return true;
    }

    bool deQueue() {
        if (isEmpty()) return false;
        front = front->next;
        --size;
        if (isEmpty()) front = rear = nullptr;
        return true;
    }

    int Front() { return isEmpty() ? -1 : front->val; }

    int Rear() { return isEmpty() ? -1 : rear->val; }

    bool isEmpty() { return size == 0; }

    bool isFull() { return size == capacity; }
};

5. 查找和替换模式

Given a list of strings words and a string pattern, return a list of words[i] that match pattern. You may return the answer in any order.

A word matches the pattern if there exists a permutation of letters p so that after replacing every letter x in the pattern with p(x), we get the desired word.

Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.

Example 1

Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
Output: ["mee","aqq"]
Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}. 
"ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation, since a and b map to the same letter.

Example 2

Input: words = ["a","b","c"], pattern = "a"
Output: ["a","b","c"]

Constraints:

  • 1 <= pattern.length <= 20
  • 1 <= words.length <= 50
  • words[i].length == pattern.length
  • pattern and words[i] are lowercase English letters.

代码

class Solution {
private:
    char mp[26];

    bool match(string &word, string &pattern) {
        memset(mp, 0, sizeof mp);
        for (int i = 0; i < word.size(); ++i) {
            char x = word[i], y = pattern[i];
            if (mp[x-'a'] == 0) {
                mp[x-'a'] = y;
            } else if (mp[x-'a'] != y) {
                return false;
            }
        }
        return true;
    }

public:
    vector<string> findAndReplacePattern(vector<string> &words, string pattern) {
        vector<string> result;
        for (auto &word:words) {
            if (match(word, pattern) && match(pattern, word)) result.emplace_back(word);
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值