← Static tasks

981. Time Based Key-Value Store

leetcode medium

#array#csharp#design#leetcode#medium#search#sort#string

Task

Спроектируйте структуру данных на основе времени для ключей и значений, которая может хранить несколько значений для одного и того же ключа в разные временные метки и извлекать значение ключа в определённый момент времени.

Реализуйте класс TimeMap:

TimeMap() Инициализирует объект структуры данных.

void set(String key, String value, int timestamp) Сохраняет ключ key с значением value в заданное время timestamp.

String get(String key, int timestamp) Возвращает значение, такое что set был вызван ранее с timestamp_prev <= timestamp. Если таких значений несколько, возвращается значение, связанное с наибольшим timestamp_prev. Если значений нет, возвращается "".

Пример:

Input

["TimeMap", "set", "get", "get", "set", "get", "get"]

[[], ["foo", "bar", 1], ["foo", 1], ["foo", 3], ["foo", "bar2", 4], ["foo", 4], ["foo", 5]]

Output

[null, null, "bar", "bar", null, "bar2", "bar2"]

C# solution

matched/original
public class Solution {
    public IList<int> PancakeSort(int[] A) {
        var ans = new List<int>();
        for (int valueToSort = A.Length; valueToSort > 0; valueToSort--) {
            int index = Find(A, valueToSort);
            if (index == valueToSort - 1) {
                continue;
            }
            if (index != 0) {
                ans.Add(index + 1);
                Flip(A, index + 1);
            }
            ans.Add(valueToSort);
            Flip(A, valueToSort);
        }
        return ans;
    }
    protected void Flip(int[] sublist, int k) {
        int i = 0;
        while (i < k / 2) {
            int temp = sublist[i];
            sublist[i] = sublist[k - i - 1];
            sublist[k - i - 1] = temp;
            i += 1;
        }
    }
    protected int Find(int[] a, int target) {
        for (int i = 0; i < a.Length; i++) {
            if (a[i] == target) {
                return i;
            }
        }
        return -1;
    }
}

C++ solution

auto-draft, review before submit
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    public vector<int> PancakeSort(vector<int>& A) {
        var ans = new List<int>();
        for (int valueToSort = A.size(); valueToSort > 0; valueToSort--) {
            int index = Find(A, valueToSort);
            if (index == valueToSort - 1) {
                continue;
            }
            if (index != 0) {
                ans.push_back(index + 1);
                Flip(A, index + 1);
            }
            ans.push_back(valueToSort);
            Flip(A, valueToSort);
        }
        return ans;
    }
    protected void Flip(vector<int>& sublist, int k) {
        int i = 0;
        while (i < k / 2) {
            int temp = sublist[i];
            sublist[i] = sublist[k - i - 1];
            sublist[k - i - 1] = temp;
            i += 1;
        }
    }
    protected int Find(vector<int>& a, int target) {
        for (int i = 0; i < a.size(); i++) {
            if (a[i] == target) {
                return i;
            }
        }
        return -1;
    }
}

Java solution

auto-draft, review before submit
import java.util.*;
import java.math.*;

// Auto-generated Java draft from the C# solution. Review API differences before LeetCode submit.
public class Solution {
    public List<int> PancakeSort(int[] A) {
        var ans = new List<int>();
        for (int valueToSort = A.length; valueToSort > 0; valueToSort--) {
            int index = Find(A, valueToSort);
            if (index == valueToSort - 1) {
                continue;
            }
            if (index != 0) {
                ans.add(index + 1);
                Flip(A, index + 1);
            }
            ans.add(valueToSort);
            Flip(A, valueToSort);
        }
        return ans;
    }
    protected void Flip(int[] sublist, int k) {
        int i = 0;
        while (i < k / 2) {
            int temp = sublist[i];
            sublist[i] = sublist[k - i - 1];
            sublist[k - i - 1] = temp;
            i += 1;
        }
    }
    protected int Find(int[] a, int target) {
        for (int i = 0; i < a.length; i++) {
            if (a[i] == target) {
                return i;
            }
        }
        return -1;
    }
}

Go solution

matched/original
package main

func pancakeSort(A []int) []int {
    var ans []int
    for valueToSort := len(A); valueToSort > 0; valueToSort-- {
        index := find(A, valueToSort)
        if index == valueToSort-1 {
            continue
        }
        if index != 0 {
            ans = append(ans, index+1)
            flip(A, index+1)
        }
        ans = append(ans, valueToSort)
        flip(A, valueToSort)
    }
    return ans
}

func flip(sublist []int, k int) {
    i := 0
    for i < k/2 {
        sublist[i], sublist[k-i-1] = sublist[k-i-1], sublist[i]
        i++
    }
}

func find(a []int, target int) int {
    for i, val := range a {
        if val == target {
            return i
        }
    }
    return -1
}

Explanation

Algorithm

Создайте hashmap keyTimeMap, который хранит строку в качестве ключа и другой hashmap в качестве значения, как обсуждалось выше.

В функции set() сохраните значение в позиции timestamp в корзине ключа keyTimeMap, т.е. keyTimeMap[key][timestamp] = value.

В функции get() итерируйтесь по всем временам в порядке убывания от timestamp до 1. Для любого времени во время итерации, если существует значение в корзине ключа, верните это значение. В противном случае, в конце верните пустую строку.

😎