Showing posts with label math. Show all posts
Showing posts with label math. Show all posts

Wednesday, February 27, 2019

829. Consecutive Numbers Sum

829. Consecutive Numbers Sum
Hard
Given a positive integer N, how many ways can we write it as a sum of consecutive positive integers?
Example 1:
Input: 5
Output: 2
Explanation: 5 = 5 = 2 + 3
Example 2:
Input: 9
Output: 3
Explanation: 9 = 9 = 4 + 5 = 2 + 3 + 4
Example 3:
Input: 15
Output: 4
Explanation: 15 = 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5
Note: 1 <= N <= 10 ^ 9.
---------------------
求等差数列为1,和为N的数列的个数,假设数列的首项为x,项数是m,则如果存在这一数列,N = (x + (x + m - 1)) * m / 2. 那么我们就遍历m的可能性

O(lgN)
ref: https://zhanghuimeng.github.io/post/leetcode-829-consecutive-numbers-sum/
class Solution {
    public int consecutiveNumbersSum(int N) {
        int rt = 0;
        
        for (int m = 1; ; m++) {
            int mx = N - (m - 1) * m / 2;
            if (mx <= 0) break;
            if (mx % m == 0) rt++;
        }
        
        return rt;
    }
}

Wednesday, December 18, 2013

Day 58, #42, #43, #55, Trapping Rain Water, Multiply Strings, Jump Game II

Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.


The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
-----------------------------------------------------------------------------------
O(n) solution. for each bar, find the max height bar on the left and right. then for this bar it can hold min(max_left, max_right) - height
class Solution {
public:
    int trap(int A[], int n) {
        vector<int> leftMax(n,0);
        vector<int> rightMax(n,0);
        
        // get left max for each element
        for (int i = 1; i < n; i++) {
            leftMax[i] = max(leftMax[i - 1],A[i - 1]);
        }
        
        // get right max for each element
        for (int i = n - 2; i >= 0; i--) {
            rightMax[i] = max(rightMax[i + 1], A[i + 1]);
        }
        
        int sum = 0;
        for (int i = 0; i < n; i++) {
            int water = min(leftMax[i],rightMax[i]) - A[i]; 
            if (water > 0) {
                sum += water; 
            }
        }
        return sum;
    }
};
Update on Nov-6th-2014
come back
Solution #2, if leftMax < rightMax, leftIndex can contain (leftMax - A[leftIndex]) water, regardless what it looks like between leftIndex and rightIndex
class Solution {
public:
    int trap(int A[], int n) {
        int sum = 0;
        int leftMax = 0, rightMax = 0;
        int leftIndex = 0, rightIndex = n - 1;
        
        while (leftIndex <= rightIndex) {
            leftMax = max(leftMax,A[leftIndex]);
            rightMax = max(rightMax,A[rightIndex]);
            if (leftMax < rightMax) {
                sum += leftMax - A[leftIndex];
                leftIndex++;
            }else {
                sum += rightMax - A[rightIndex];
                rightIndex--;
            }
        }
        
        return sum;
    }
};
Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string.
Note: The numbers can be arbitrarily large and are non-negative.
--------------------------------------
Multiply numbers using straightforward math
class Solution {
public:
    string multiply(string num1, string num2) {
        int len1 = num1.length(), len2 = num2.length();
        string sum(len1 + len2,'0');
      
        for (int i = len1 - 1; i >= 0; i--) {
            int carry = 0;
            for (int j = len2 - 1; j >= 0; j--) {
                int cur = (sum[i + j + 1] - '0') + carry + (num1[i] - '0') * (num2[j] - '0');
                sum[i + j + 1] = cur % 10 + '0';
                carry = cur / 10;
            }
            sum[i] += carry;   
        }
        
        int start = 0;
        while (sum[start] == '0') {
            start++;
        }
        if (start == sum.length()) return "0";
        return sum.substr(start);
    }
};
Jump Game II
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
---------------------------------------------------------------------------
Greedy, the point of this question is to find the largest distance with minimum steps
Every time 'i' passes curMax, increment step


class Solution {
public:
    int jump(int A[], int n) {
        int curMax = 0, newMax = 0;
        int step = 0;
        for (int i = 0; i < n; i++) {
            if (i > curMax) {
                // set up new max from old steps
                curMax = newMax;
                step++;
            }
            newMax = max(newMax,i + A[i]); // this line should be placed after if condition, 'cause new step has been made
        }
        return step;
    }
};
Update on Nov-7th-2014
a slightly different version, handles the case where the goal cannot be reached
class Solution {
public:
    int jump(int A[], int n) {
        if (n == 1) return 0;
        int step = 1;
        int currentReach = A[0];
        int maxCanReach = A[0];
        
        for (int i = 1; i < n; i++) {
            if (i > currentReach) {
                // to handle cases where the end cannot be reached
                if (currentReach == maxCanReach) {
                    return -1;
                }
                step++;
                currentReach = maxCanReach;
            }
            maxCanReach = max(maxCanReach,i + A[i]);
        }
        
        return step;
    }
};

Thursday, April 4, 2013

Day 10, 13 Roman to Integer

Roman to Integer
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
---------------------------
first, setup a dictionary, then walk through the whole string
according to the Roman numeral rule, if str[i] < str[i+1], then str[i] should be negative
watch out for the end element of the string, it could be compared to an unknown  value.
 
class Solution {
public:
    int romanToInt(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        unordered_map<char,int> k;
        k['I'] = 1;
        k['V'] = 5;
        k['X'] = 10;
        k['L'] = 50;
        k['C'] = 100;
        k['D'] = 500;
        k['M'] = 1000;
        int sum=0;
        for (int i=0;i<s.length();i++) {
            int sign = 1;
            if (k[s[i]] < k[s[i+1]]) {
                sign = -1;  
            }
            sum = sum + k[s[i]] * sign;
        }
        return sum;
    }
};
Added on Sep-02-2014
Handled final char in string
class Solution {
public:
    unordered_map<char,int> populateMap() {
        unordered_map<char,int> dic;
        dic['I'] = 1;
        dic['V'] = 5;
        dic['X'] = 10;
        dic['L'] = 50;
        dic['C'] = 100;
        dic['D'] = 500;
        dic['M'] = 1000;
        dic['e'] = 0;
        
        return dic;
    }

    int romanToInt(string s) {
        unordered_map<char,int> dic = populateMap();
        int ret = 0;
        s += 'e';
        
        for (int i = 0; i < s.length(); i++) {
            if (dic[s[i]] < dic[s[i + 1]]) {
                ret += dic[s[i + 1]] - dic[s[i]]; 
                i++;
            }else {
                ret += dic[s[i]];
            }    
        }
        return ret;
    }
};

Wednesday, April 3, 2013

Day 9, 9 Palindrome Number

Palindrome Number

Determine whether an integer is a palindrome. Do this without extra space.
Some hints: Could negative integers be palindromes? (ie, -1)
If you are thinking of converting the integer to string, note the restriction of using extra space.
You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case?
There is a more generic way of solving this problem.

 
class Solution {
public:
    bool isPalindrome(int x) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (x < 0) { 
            return false;
        }
        
        // reverse
        int temp = x;
        int y = 0;
        while (temp>0) { 
            y = 10 * y + temp % 10;
            temp = temp / 10;
        }
        
        if (x != y) {
            return false;
        }
        return true;
    }
};




Tuesday, April 2, 2013

Day 8, 8 String to Integer (atoi)

 String to Integer (atoi)

Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
Requirements for atoi: The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.
The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.
If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.
If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.

Solution #1
class Solution {
public:
    int myAtoi(string str) {
        int rt = 0,i = 0;
        int sign = 1;
        while (isspace(str[i])) {
            i++;
        }
        if (str[i] == '-') {
            i++;
            sign = -1;
        }else if (str[i] == '+') i++;
        
        while (i < str.length() && isdigit(str[i])) {
            if (sign == 1 && (rt > 214748364 || (rt == 214748364 && str[i] - '0' > 7))) {
                return INT_MAX;
            }
            if (sign == -1 && (rt > 214748364 || (rt == 214748364 && str[i] - '0' > 8))) {
                return INT_MIN;
            }
            rt = rt * 10 + str[i] - '0';
            i++;
        }
        
        return rt * sign;
    }
};
Solution #2
declare result as long long type;
class Solution {
 public:
  int atoi(const char *str) {
    long long r = 0;
    int i = 0;
    bool negtive = false;
    while(str[i] == ' ')i++;
    if(str[i] == '+') i++;
    else if (str[i] == '-') {
      negtive = true;
      i++;
    }
    for(; str[i] >= '0' && str[i] <= '9'; i++) {
      int d = str[i] - '0';
      if(negtive)r = 10*r - d;
      else r = 10*r + d;
      if( r > numeric_limits<int>::max()) return numeric_limits<int>::max();
      if( r < numeric_limits<int>::min()) return numeric_limits<int>::min();
    }
    return r;
  }