OAmaster
— / 4已做

A password detection system for HackerRank accounts detects a password as similar if the number of vowels is equal to the number of consonants in the password. Passwords consist of lowercase English characters only, and vowels are ('a', 'e', 'i', 'o', 'u'). To check the strength of a password and how easily it can be hacked, some manipulations can be made to the password. In one operation, any character of the string can either be incremented or decremented. For example, 'f' can be incremented to 'g', or decremented to 'e'. Note that character 'a' cannot be decremented and 'z' cannot be incremented. Find the minimum number of operations in which the password can be made similar. Function Description Complete the function countMinimumOperations in the editor below. countMinimumOperations has the following parameter:

  • string password: the password Returns int: the minimum number of operations

Constraints

  • 1 ≤ password.length ≤ 10^5
  • password 仅由小写英文字母组成

解法

设元音数 v、辅音数 c,差 d = v - c。需要把 |d|/2 个字符在元音/辅音之间互转。对每个待转字符计算最近的相反类型字符的距离(如 v -> nearest consonant in alphabet),贪心选 |d|/2 个最小成本即可。时间复杂度 O(n log n)。

def countMinimumOperations(password: str) -> int:
    vowels = set('aeiou')
    v_chars = [c for c in password if c in vowels]
    c_chars = [c for c in password if c not in vowels]
    diff = len(v_chars) - len(c_chars)
    if diff == 0: return 0
    # Convert from larger group to smaller group |diff|/2 characters
    if diff > 0:
        candidates = v_chars; target_set = set('bcdfghjklmnpqrstvwxyz')
    else:
        candidates = c_chars; target_set = vowels
    def min_dist(ch):
        return min(abs(ord(ch) - ord(t)) for t in target_set)
    costs = sorted(min_dist(c) for c in candidates)
    return sum(costs[:abs(diff) // 2])
class Solution {
    int countMinimumOperations(String password) {
        Set<Character> vowels = new HashSet<>(Arrays.asList('a','e','i','o','u'));
        List<Character> vChars = new ArrayList<>(), cChars = new ArrayList<>();
        for (char c : password.toCharArray()) (vowels.contains(c) ? vChars : cChars).add(c);
        int diff = vChars.size() - cChars.size();
        if (diff == 0) return 0;
        List<Character> cands; Set<Character> targets;
        if (diff > 0) {
            cands = vChars;
            targets = new HashSet<>();
            for (char c = 'a'; c <= 'z'; c++) if (!vowels.contains(c)) targets.add(c);
        } else {
            cands = cChars; targets = vowels;
        }
        List<Integer> costs = new ArrayList<>();
        for (char c : cands) {
            int best = Integer.MAX_VALUE;
            for (char t : targets) best = Math.min(best, Math.abs(c - t));
            costs.add(best);
        }
        Collections.sort(costs);
        int total = 0;
        for (int i = 0; i < Math.abs(diff) / 2; i++) total += costs.get(i);
        return total;
    }
}
class Solution {
public:
    int countMinimumOperations(string password) {
        set<char> vowels = {'a','e','i','o','u'};
        vector<char> vChars, cChars;
        for (char c : password) (vowels.count(c) ? vChars : cChars).push_back(c);
        int diff = (int)vChars.size() - (int)cChars.size();
        if (diff == 0) return 0;
        vector<char>& cands = diff > 0 ? vChars : cChars;
        set<char> targets;
        if (diff > 0) for (char c = 'a'; c <= 'z'; c++) { if (!vowels.count(c)) targets.insert(c); }
        else targets = vowels;
        vector<int> costs;
        for (char c : cands) {
            int best = INT_MAX;
            for (char t : targets) best = min(best, abs(c - t));
            costs.push_back(best);
        }
        sort(costs.begin(), costs.end());
        int total = 0;
        for (int i = 0; i < abs(diff) / 2; i++) total += costs[i];
        return total;
    }
};

A company wants to track the usage of its mobile app by recording users' login times and dates. The company stores the login information in a 2D array of strings, logs, which contains data in the format ["/username<user_id>","login_time","login_date"]. They need a function to process the logs and output a 2D array of strings, sorted lexicographically, that displays the number of times each user logs in per day in the format ["/username<user_id>","login_date","login_count"]. It must filter invalid data in the input array rather than write it to the output array. Users should be sorted in lexicographic order based on their user_id. Each user's information should be sorted by the login date in ascending order. The date and time are provided in YYYY-MM-DD and HH:MM:SS format, and the username has the format "userX" where X is an integer. Function Description Complete the function countUserLogins in the editor. countUserLogins has the following parameter:

  • String[][] logs: a 2D array of strings containing the login data Returns String[][]: a 2D array of strings containing the user login counts per day, sorted lexicographically

Constraints

  • 1 ≤ n (size of logs) ≤ 10⁵
  • 2000 ≤ YYYY ≤ 3000
  • 0 ≤ MM, DD, HH, SS ≤ 99
  • YYYY, MM, DD, HH, and SS are all integers.
  • All usernames are of the format "user" appended with some integer (user_id).

Example 1

Input:

logs = [["user1","09:00:00","2021-01-01"],["user1","13:00:00","2021-01-01"],["user2","14:00:00","2021-01-01"],["user1","20:00:00","2021-01-02"],["user2","21:00:00","2021-01-01"]]

Output:

[["user1","2021-01-01","2"],["user1","2021-01-02","1"],["user2","2021-01-01","2"]]

Explanation: The function should output the login counts for each user per day, sorted lexicographically, resulting in a 2-d array of strings in the format [["user1","2021-01-01","3"],["user1","2021-01-02","1"],["user2","2021-01-01","1"]].

Example 2

Input:

logs = [["user1","09:00:00","2021-01-01"],["user1","13:00:00","2021-01-01"],["user2","14:00:00","2021-01-01"],["user1","20:00:00","2021-01-01"],["user2","21:00:00","2021-01-01"], ["user3","25:00:00","2021-01-01"], ["user4","22:00:00","2021-02-29"]]

Output:

[["user1","2021-01-01","3"],["user2","2021-01-01","2"]]

Explanation:

  • user1 logs into the system 3 times on 2021-01-01
  • user2 logs into the system 3 times on 2021-01-01
  • entry 6 in the logs has an invalid time, 25:00:00.
  • entry 7 in the logs has an invalid data, 2021-02-29.

解法

校验时间 HH < 24, MM < 60, SS < 60;日期合法(含闰年/月天数)。按 (user, date) 计数,再按字典序输出。时间复杂度 O(n log n)。

from typing import List
from collections import defaultdict
from datetime import datetime

def countUserLogins(logs: List[List[str]]) -> List[List[str]]:
    counter = defaultdict(int)
    for user, t, d in logs:
        try:
            h, m, s = map(int, t.split(':'))
            if not (0 <= h < 24 and 0 <= m < 60 and 0 <= s < 60): continue
            datetime.strptime(d, "%Y-%m-%d")
        except ValueError:
            continue
        counter[(user, d)] += 1
    keys = sorted(counter.keys())
    return [[u, d, str(counter[(u, d)])] for u, d in keys]
class Solution {
    String[][] countUserLogins(String[][] logs) {
        Map<String, Integer> counter = new TreeMap<>();
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("uuuu-MM-dd").withResolverStyle(java.time.format.ResolverStyle.STRICT);
        for (String[] row : logs) {
            try {
                String[] tp = row[1].split(":");
                int h = Integer.parseInt(tp[0]), m = Integer.parseInt(tp[1]), s = Integer.parseInt(tp[2]);
                if (h < 0 || h >= 24 || m < 0 || m >= 60 || s < 0 || s >= 60) continue;
                java.time.LocalDate.parse(row[2], fmt);
            } catch (Exception e) { continue; }
            counter.merge(row[0] + "\t" + row[2], 1, Integer::sum);
        }
        List<String[]> out = new ArrayList<>();
        for (Map.Entry<String, Integer> e : counter.entrySet()) {
            String[] kp = e.getKey().split("\t");
            out.add(new String[]{kp[0], kp[1], String.valueOf(e.getValue())});
        }
        return out.toArray(new String[0][]);
    }
}
class Solution {
public:
    vector<vector<string>> countUserLogins(vector<vector<string>>& logs) {
        map<pair<string, string>, int> counter;
        for (auto& row : logs) {
            int h, m, s;
            if (sscanf(row[1].c_str(), "%d:%d:%d", &h, &m, &s) != 3) continue;
            if (h < 0 || h >= 24 || m < 0 || m >= 60 || s < 0 || s >= 60) continue;
            int yy, mm, dd;
            if (sscanf(row[2].c_str(), "%d-%d-%d", &yy, &mm, &dd) != 3) continue;
            if (mm < 1 || mm > 12 || dd < 1) continue;
            int dim[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
            bool leap = (yy % 4 == 0 && yy % 100 != 0) || yy % 400 == 0;
            if (mm == 2 && leap) dim[1] = 29;
            if (dd > dim[mm - 1]) continue;
            counter[{row[0], row[2]}]++;
        }
        vector<vector<string>> out;
        for (auto& [k, v] : counter) out.push_back({k.first, k.second, to_string(v)});
        return out;
    }
};

Given an array price[1-n] and m (discount), find the minimum price to spend to buy all the items. Use the following formula to apply the coupon: price[i] / 2^x, where x is the number of coupons used, and i is the index of the item in the array. Function Description Complete the function findMinimumPriceToSpend in the editor. findMinimumPriceToSpend has the following parameters:

    1. int[] price: an array of integers representing the price of each item
    1. int m: the number of discounts available Returns int: the minimum price to spend

Example 1

Input:

price = [1, 2, 3]
m = 2

Output:

3

Explanation:

解法

贪心 + 大顶堆:每张优惠券都用在当前价格最大的商品上(半价后放回)。注意 floor 整除,价格为 0 后不再受益。时间复杂度 O((n + m) log n)。

import heapq
from typing import List

def findMinimumPriceToSpend(price: List[int], m: int) -> int:
    h = [-p for p in price]
    heapq.heapify(h)
    while m > 0 and -h[0] > 0:
        top = -heapq.heappop(h)
        heapq.heappush(h, -(top // 2))
        m -= 1
    return -sum(h)
class Solution {
    long findMinimumPriceToSpend(int[] price, int m) {
        PriorityQueue<Long> pq = new PriorityQueue<>(Comparator.reverseOrder());
        for (int p : price) pq.add((long) p);
        while (m > 0 && pq.peek() > 0) {
            long top = pq.poll();
            pq.add(top / 2);
            m--;
        }
        long sum = 0;
        for (long v : pq) sum += v;
        return sum;
    }
}
class Solution {
public:
    long long findMinimumPriceToSpend(vector<int>& price, int m) {
        priority_queue<long long> pq;
        for (int p : price) pq.push(p);
        while (m > 0 && pq.top() > 0) {
            long long top = pq.top(); pq.pop();
            pq.push(top / 2);
            m--;
        }
        long long sum = 0;
        while (!pq.empty()) { sum += pq.top(); pq.pop(); }
        return sum;
    }
};

Given an array of integers, the cost to change an element is the absolute difference between its initial value and its new value. For example, if the element is initially 10, it can be changed to 7 or 13 for a cost of 3. Determine the minimum cost to sort the array either ascending or descending along its length. Function Description Complete the function modifyArray in the editor. modifyArray has the following parameters:

  • int arr[n]: an array of integers Returns int: an integer that denotes the minimum cost required to make the array ascending (non-decreasing) or descending (non-increasing) along its length.

Constraints

  • 1 ≤ n ≤ 10³
  • 1 ≤ arr[i] ≤ 10⁹

Example 1

Input:

arr = [9, 8, 7, 2, 3, 3]

Output:

1

Explanation: N/A :)

Example 2

Input:

arr = [1, 2, 3, 3, 4]

Output:

0

Explanation: The array arr is already sorted in ascending order. The minimum cost to sort it in ascending order is 0.

Example 3

Input:

arr = [0, 1, 2, 5, 6, 5, 7]

Output:

1

Explanation: Only arr[5] = 5 violates the order for an ascending sort. If the value 5 is increased to 6, the arr will be sorted in ascending order: arr' = [0, 1, 2, 5, 6, 6, 7] The cost is |arr[5] - [5 - 6]| = 1 :)

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁
Pro 会员

解锁全部 1 道题的解法

题面你已经看到了 — 解法 + 三语代码 + 复杂度推导 + 边界讨论, Pro 解锁.

Pro 解锁全部
  • 📚1000+ 道真实北美 OA, Python / Java / C++ 三语题解
  • 📊个人 dashboard + 进度可视化 + 14 天活跃图
  • 📝题目笔记跨设备同步 + 个人复盘库
  • 🔓随时取消下次续费, Stripe Customer Portal 自助管理
$12/月($98/年, 一次付清省 32%)

≈ 北美 SWE 工资 10 分钟 · LeetCode Premium $35/月 的 23%