zoukankan      html  css  js  c++  java
  • Weekly Contest 128

    1012. Complement of Base 10 Integer


    Every non-negative integer N has a binary representation.  For example, 5 can be represented as "101" in binary, 11 as "1011" in binary, and so on.  Note that except for N = 0, there are no leading zeroes in any binary representation.

    The complement of a binary representation is the number in binary you get when changing every 1 to a 0 and 0 to a 1.  For example, the complement of "101" in binary is "010" in binary.

    For a given number N in base-10, return the complement of it's binary representation as a base-10 integer.

    Example 1:

    Input: 5
    Output: 2
    Explanation: 5 is "101" in binary, with complement "010" in binary, which is 2 in base-10.
    

    Example 2:

    Input: 7
    Output: 0
    Explanation: 7 is "111" in binary, with complement "000" in binary, which is 0 in base-10.
    

    Example 3:

    Input: 10
    Output: 5
    Explanation: 10 is "1010" in binary, with complement "0101" in binary, which is 5 in base-10.
    

    Note:

    1. 0 <= N < 10^9

    Approach #1: Math. [C++]

    class Solution {
    public:
        int bitwiseComplement(int N) {
            int X = 1;
            while (N > X) X = X * 2 + 1;
            return X ^ N;
        }
    };
    

      

    Analysis:

    Claim ----- The XOR operation evaluates the difference in the individual bits, i.e it gives information about whether the bits are identical or not.

    Proof ----- It's easy once youknow the definition of XOR.  0^0 = 1^1 = 0 (as the bits don't differ), whereas 0^1 = 1^0 = 1 (as the bits are difference).

    Claim ----- XOR of identical numbers is zero.

    Proof ----- As argued above, the bits of identical numbers do not differ at any position. Hence, XOR is zero.

    Claim ----- 0 XOR any number is the number itself.

    Proof ----- XOR gives us the bit difference. Since all the bits in 0 are unset, therefore the difference in bits is the number itself.

    Claim ----- XOR of a number with its complement results in a number with all set bits.

    Proof ----- This is trivial,  since bits of a number and its complement differ at every position(according to the definition of complement).

    So, number ^ complement = all_set_bits ==> number ^ number ^ complement = number ^ all_set_bits ===> 0 ^ complement = number ^ all_set_bits

    So, complement = number ^ all_set_bits.

    So, we find out the number containing all the set bits and XOR with the original number to get the answer.

    Reference:

    https://leetcode.com/problems/complement-of-base-10-integer/discuss/256734/Detailed-Explanation-using-XOR-C%2B%2BJavaScript

    1013. Pairs of Songs With Total Durations Divisible by 60

    In a list of songs, the i-th song has a duration of time[i] seconds. 

    Return the number of pairs of songs for which their total duration in seconds is divisible by 60.  Formally, we want the number of indices i < j with (time[i] + time[j]) % 60 == 0.

    Example 1:

    Input: [30,20,150,100,40]
    Output: 3
    Explanation: Three pairs have a total duration divisible by 60:
    (time[0] = 30, time[2] = 150): total duration 180
    (time[1] = 20, time[3] = 100): total duration 120
    (time[1] = 20, time[4] = 40): total duration 60
    

    Example 2:

    Input: [60,60,60]
    Output: 3
    Explanation: All three pairs have a total duration of 120, which is divisible by 60.
    

    Note:

    1. 1 <= time.length <= 60000
    2. 1 <= time[i] <= 500
     

    Approach #1: Brute force + Map. [C++]

    class Solution {
    public:
        int numPairsDivisibleBy60(vector<int>& time) {
            int ans = 0;
            int len = time.size();
            map<int, vector<int>> m;
            vector<int> duration = {60, 120, 180, 240, 300, 360, 420, 480, 540, 600,
                                    660, 720, 780, 840, 900, 960, 1020};
            for (int i = 0; i < len; ++i) m[time[i]].push_back(i);
            for (int i = 0; i < len; ++i) {
                for (int j = 0; j < duration.size(); ++j) {
                    if (duration[j] - time[i] > 0) {
                        int tmp = duration[j] - time[i];
                        if (m.count(tmp)) {
                            int count = m[tmp].end() - upper_bound(m[tmp].begin(), m[tmp].end(), i);
                            ans += count;
                        }
                    }
                }
            }
            
            return ans;
        }
    };
    

      

    Approach #2: Orz.

        int numPairsDivisibleBy60(vector<int>& time) {
            vector<int> c(60);
            int res = 0;
            for (int t : time) {
                res += c[(60 - t % 60) % 60];
                c[t % 60] += 1;
            }
            return res;
        }
    

      

    Analysis:

    Calculate the time%60 then it will be exactly same as two sum problem.

    Reference:

    https://leetcode.com/problems/pairs-of-songs-with-total-durations-divisible-by-60/discuss/256738/JavaC%2B%2BPython-Two-Sum-with-K-60

    1014. Capacity To Ship Packages Within D Days

    A conveyor belt has packages that must be shipped from one port to another within Ddays.

    The i-th package on the conveyor belt has a weight of weights[i].  Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship.

    Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within Ddays.

    Example 1:

    Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5
    Output: 15
    Explanation: 
    A ship capacity of 15 is the minimum to ship all the packages in 5 days like this:
    1st day: 1, 2, 3, 4, 5
    2nd day: 6, 7
    3rd day: 8
    4th day: 9
    5th day: 10
    
    Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed. 
    

    Example 2:

    Input: weights = [3,2,2,4,1,4], D = 3
    Output: 6
    Explanation: 
    A ship capacity of 6 is the minimum to ship all the packages in 3 days like this:
    1st day: 3, 2
    2nd day: 2, 4
    3rd day: 1, 4
    

    Example 3:

    Input: weights = [1,2,3,1,1], D = 4
    Output: 3
    Explanation: 
    1st day: 1
    2nd day: 2
    3rd day: 3
    4th day: 1, 1
    

    Note:

    1. 1 <= D <= weights.length <= 50000
    2. 1 <= weights[i] <= 500

    Approach #1: Binary search. [C++]

    class Solution {
    public:
        int shipWithinDays(vector<int>& weights, int D) {
            int left = *max_element(weights.begin(), weights.end());
            int right = 25000000;
            while (left < right) {
                int mid = (right + left) / 2;
                int need = 1, cur = 0;
                for (int i = 0; i < weights.size() && need <= D; cur += weights[i++]) {
                    if (cur + weights[i] > mid)
                        cur = 0, need++;
                }
                if (need > D) left = mid + 1;
                else right = mid;
            }
            return left;
        }
    };
    

      

    Analysis:

    Given the number of bags, return the minimum capacity of each bag, so that we can put items one by one into all bags.

    Reference:

    https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/discuss/256729/JavaC%2B%2BPython-Binary-Search

    1015. Numbers With Repeated Digits

    Given a positive integer N, return the number of positive integers less than or equal to N that have at least 1 repeated digit.

    Example 1:

    Input: 20
    Output: 1
    Explanation: The only positive number (<= 20) with at least 1 repeated digit is 11.
    

    Example 2:

    Input: 100
    Output: 10
    Explanation: The positive numbers (<= 100) with atleast 1 repeated digit are 11, 22, 33, 44, 55, 66, 77, 88, 99, and 100.
    

    Example 3:

    Input: 1000
    Output: 262
    

    Note:

    1. 1 <= N <= 10^9
     

     Approach #1: 

    class Solution {
    public:
        int numDupDigitsAtMostN(int N) {
            int invalid = 0;
            
            int c = floor(log10(N+1)) + 1;
            for (int i = 0; i < c-1; ++i) {
                invalid += 9 * perm(9, i);
            }
            
            int digits = 0;
            for (int i = 0; i < c; ++i) {
                int digit = ((N+1) / (int)pow(10, c-i-1)) % 10;
                
                for (int j = (i > 0 ? 0 : 1); j < digit; ++j) {
                    if (((digits >> j) & 1) == 0) {
                        invalid += perm(9 - i, c - i - 1);
                    }
                }
                
                if ((digits >> digit) & 1) break;
                digits |= 1 << digit;
            }
            
            return N - invalid;
        }
        
        int perm(int m, int n) {
            int out = 1;
            while (m > 1 && n > 0) {
                out *= m;
                m--;
                n--;
            }
            
            return out;
        }
    };
    

      

    Analysis:

    For example, with the number 350, we have 3 digits, meaning we can start by finding all invalid numbers from 0 to 99 (e.g. the first two digits). To start, let's assuming we only have 1 digit available. In this case, we can't vary any other digits in the number since there are none, and because there is only 1 digit they are all invalid. Thus, since there are 9 total numbers with 1 digit, we have 9 invalid permutations for this digit. Similary, for 2 digits, we have 1 digit we can vary (e.g. 1x has x that can be varied, 2y has y that can be varied, so on and so forth). Plugging that into our formula, we have perm(9,1) which results in 9. Because there are 9 possible digits for the first digit, we can multiply the result by 9 (perm(9, 1) * 9) which gives us 81 invalid digits. Adding that onto our first result of 9, and we get 90 invalid for a number range of 1-99 (meaning we have 9 valid digits in that range).

    At this point, for the number 350, we know that thare are at least 90 invalid digits from 1 - 100 as a result (since 100 is valid). Now however we need to count the number of invalid digits from 100 - 350. This can be done by varying each of the digits in 351 (e.g. N+1), and finding the valid permutations of that as a result. For example:

    3XX -> perm(9-0, 3-0-1) -> perm(9, 2)
    X5X -> perm(9-1, 3-1-1) -> perm(8, 1)
    XX1 -> perm(9-2, 3-2-1) -> perm(7, 0)

    We then add this number of invalid permutations to our count based on the number we have. However, if we have previously seen a number in that range. we ignore it. For example, when we get to the 5 in 351, we will only add perm(8, 1)'s result 4 time, since the third time has alredy been accounted for when we went over the 3 in 351. Once we've done all of this, we can simply subtract our number of nvalid numbers from our original number N to get our result.

    Here is what this process looks like in action:

    350 -> 351
    invalid digits -> 0
    
    1 digit -> X -> perm(9, 0) * 9 -> 9 invalid digits
    2 digits -> YX -> perm(9, 1) * 9 -> 81 invalid digits
    invalid digits -> 90
    
    0XX -> invalid so don't count the invalid digits.
    1XX -> perm(9, 2) -> 72 invalid digits
    2XX -> perm(9, 2) -> 72 invalid digits
    3XX -> stop counting invalid numbers for the first digit.
    X0X -> perm(8, 1) -> 8 invalid digits
    X1X -> perm(8, 1) -> 8 invalid digits
    X2X -> perm(8, 1) -> 8 invalid digits
    X3X -> perm(8, 1) -> 8 invalid digits -> but because we've already looked at the digit 3 previously we can skip this.
    X4X -> perm(8, 1) -> 8 invalid digits
    X5X -> stop counting invalid numbers for the second digit.
    XX0 -> perm(7, 0) -> 1 invalid digit
    XX1 -> stop counting invalid numbers for the third and final digit.
    invalid digits -> 267
    
    result -> 350 - 267 = 83

    Reference:

    https://leetcode.com/problems/numbers-with-repeated-digits/discuss/257241/C%2B%2B-with-Alternative-Explanation

     
    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    监视和调整硬件性能
    ASP.NET MVC三个重要的描述对象:ActionDescriptor
    REST in Practice
    软硬件错误的排查之道
    OMCS 多媒体连接系统
    逻辑层 vs 物理层
    深入浅出裸测之道单元测试的单元化
    简单的网络爬虫实现
    WCF返回JSON与传入JSON(普通参数或对象)
    .NET程序员的一个礼物——TypeMonster
  • 原文地址:https://www.cnblogs.com/h-hkai/p/10547817.html
Copyright © 2011-2022 走看看