LeetCode之Math題目彙總

Add Binary

Given two binary strings, return their sum (also a binary string).

For example,
a = "11"
b = "1"
Return "100".


    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {

        if (l1 == null && l2 == null) {
            return null;
        }

        if (l1 == null) {
            return l2;
        }

        if (l2 == null) {
            return l1;
        }

        ListNode p1 = l1;
        ListNode p2 = l2;

        int carry = 0;

        ListNode head = new ListNode(0);
        ListNode result = head;

        while (carry != 0 || p1 != null || p2 != null) {

            int v1 = 0;
            if (p1 != null) {
                v1 = p1.val;
                p1 = p1.next;
            }

            int v2 = 0;
            if (p2 != null) {
                v2 = p2.val;
                p2 = p2.next;
            }

            int tmp = v1 + v2 + carry;
            carry = tmp / 10;
            head.next = new ListNode(tmp % 10);
            head = head.next;
        }

        return result.next;
    }

Add Digits

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.

For example:

Given num = 38, the process is like: 3 + 8 = 111 + 1 = 2. Since 2 has only one digit, return it.

Follow up:
Could you do it without any loop/recursion in O(1) runtime?

Hint:

  1. A naive implementation of the above process is trivial. Could you come up with other methods?
  2. What are all the possible results?
  3. How do they occur, periodically or randomly?
  4. You may find this Wikipedia article useful.

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.


dr(n)=n9n19
    public int addDigits(int num) {
        return 1 + (num - 1) % 9;
    }

Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8


    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {

        if (l1 == null && l2 == null) {
            return null;
        }

        if (l1 == null) {
            return l2;
        }

        if (l2 == null) {
            return l1;
        }

        ListNode p1 = l1;
        ListNode p2 = l2;

        int carry = 0;

        ListNode head = new ListNode(0);
        ListNode result = head;

        while (carry != 0 || p1 != null || p2 != null) {

            int v1 = 0;
            if (p1 != null) {
                v1 = p1.val;
                p1 = p1.next;
            }

            int v2 = 0;
            if (p2 != null) {
                v2 = p2.val;
                p2 = p2.next;
            }

            int tmp = v1 + v2 + carry;
            carry = tmp / 10;
            head.next = new ListNode(tmp % 10);
            head = head.next;
        }

        return result.next;
    }

Basic Calculator

Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -non-negative integers and empty spaces .

You may assume that the given expression is always valid.

Some examples:

"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23

Note: Do not use the eval built-in library function.


題目中只有+ - ( )。遍歷字符串,對於每個字符c:

  1. 如果是數字,則一直遍歷到非數字字符,把數字找出,並與結果相加
  2. 如果是+-符號,將sign設置成對應的值
  3. 如果是(,將rt和sign壓入棧中,重置rt和sign
  4. 如果是),將sign和rt彈出棧,並計算結果
    public int calculate(String s) {

        if (s == null || s.length() == 0) {
            return 0;
        }

        Stack<Integer> stack = new Stack<Integer>();

        int sign = 1;// 符號位,1表示+,-1表示-
        int rt = 0;

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (Character.isDigit(c)) {
                int val = c - '0';
                // 將數字取出
                while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
                    val = val * 10 + s.charAt(++i) - '0';
                }
                rt += sign * val;
            } else if (c == '-') {
                sign = -1;
            } else if (c == '+') {
                sign = 1;
            } else if (c == '(') {
                // 按照數字、符號的順序,壓入棧
                stack.push(rt);
                stack.push(sign);
                rt = 0;
                sign = 1;
            } else if (c == ')') {
                rt = rt * stack.pop() + stack.pop();
                sign = 1;
            }
        }

        return rt;

    }

Basic Calculator II

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, +-*/ operators and empty spaces . The integer division should truncate toward zero.

You may assume that the given expression is always valid.

Some examples:

"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5

Note: Do not use the eval built-in library function.

Credits:
Special thanks to @ts for adding this problem and creating all test cases.


分兩次遍歷,第一次遍歷時,遇到乘除符號就計算;第二次遍歷,計算加減符號。

    public int calculate(String s) {

        if (s == null || s.length() == 0) {
            return 0;
        }

        Stack<Integer> stack = new Stack<Integer>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (Character.isDigit(c)) {
                int val = c - '0';
                // 將數字取出
                while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
                    val = val * 10 + s.charAt(++i) - '0';
                }
                // 棧頂是 * / 運算符,計算
                if (!stack.isEmpty()
                        && (stack.peek() == 2 || stack.peek() == 3)) {
                    int sign = stack.pop();
                    int op = stack.pop();
                    int rt = 0;
                    if (sign == 2) {
                        rt = op * val;
                    } else {
                        rt = op / val;
                    }
                    stack.push(rt);
                } else {
                    stack.push(val);
                }
            } else if (c == ' ') {
                continue;
            } else {
                switch (c) {
                case '+':
                    stack.push(0);
                    break;
                case '-':
                    stack.push(1);
                    break;
                case '*':
                    stack.push(2);
                    break;
                case '/':
                    stack.push(3);
                    break;

                }
            }
        }

        if (stack.isEmpty()) {
            return 0;
        }

        // 因爲要從左向右計算,所以要reverse
        Collections.reverse(stack);

        // 計算+-
        int rt = stack.pop();
        while (!stack.isEmpty()) {
            int sign = stack.pop();
            int op = stack.pop();
            if (sign == 0) {
                rt += op;
            } else {
                rt -= op;
            }
        }

        return rt;
    }

Divide Two Integers

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.


    public int divide(int dividend, int divisor) {

        if (divisor == 0) {
            return Integer.MAX_VALUE;
        }

        int result = 0;

        if (dividend == Integer.MIN_VALUE) {
            result = 1;
            if (divisor == -1) {
                return Integer.MAX_VALUE;
            }
            dividend += Math.abs(divisor);
        }

        if (divisor == Integer.MIN_VALUE) {
            return result;
        }

        boolean isNeg = ((dividend ^ divisor) >>> 31 == 1) ? true : false;

        dividend = Math.abs(dividend);
        divisor = Math.abs(divisor);

        int c = 0;
        while (divisor <= (dividend >> 1)) {
            divisor <<= 1;
            c++;
        }

        while (c >= 0) {
            if (dividend >= divisor) {
                dividend -= divisor;
                result += 1 << c;
            }
            divisor >>= 1;
            c--;
        }

        System.out.println(result);

        return isNeg ? -result : result;
    }

Excel Sheet Column Number

Related to question Excel Sheet Column Title

Given a column title as appear in an Excel sheet, return its corresponding column number.

For example:

    A -> 1
    B -> 2
    C -> 3
    ...
    Z -> 26
    AA -> 27
    AB -> 28 

Credits:
Special thanks to @ts for adding this problem and creating all test cases.


二十六進制

    public int titleToNumber(String s) {

        int n = 0;
        int p = 1;

        for (int i = s.length() - 1; i >= 0; i--) {
            n += (s.charAt(i) - 'A' + 1) * p;
            p *= 26;
        }

        return n;
    }

Excel Sheet Column Title

Given a positive integer, return its corresponding column title as appear in an Excel sheet.

For example:

    1 -> A
    2 -> B
    3 -> C
    ...
    26 -> Z
    27 -> AA
    28 -> AB 

Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases.


    public String convertToTitle(int n) {

        if (n < 27) {
            return (char) ('A' + (n - 1)) + "";
        }

        if (n % 26 == 0) {
            return convertToTitle(n / 26 - 1) + 'Z';
        }

        return convertToTitle(n / 26) + convertToTitle(n % 26);
    }

Factorial Trailing Zeroes

Given an integer n, return the number of trailing zeroes in n!.

**Note: **Your solution should be in logarithmic time complexity.

Credits:
Special thanks to @ts for adding this problem and creating all test cases.


結果轉換成3進制,結尾有多少個連續的0?

在面試時,曾遇到這樣的一道題:

30!結果轉換成3進制,結尾有多少個連續的0?

第一次做的話,感覺沒有思路,但是換個角度想,轉換成3進制,那麼十進制中的1~30,哪些因子相乘,纔會貢獻出三進制結尾的0呢?當然是:3的倍數

3, 6, 9, 12, 15 ,18, 21, 24, 27, 30


那麼,每一個因子貢獻了多少個0呢?

貢獻了1個0的因子

3 = 3 * 1
6 = 3 * 2
12 = 3 * 4
15 = 3 * 5
21 = 3 * 7
24 = 3 * 8
30 = 3 * 10

貢獻了2個0的因子

9 = 3 * 3
18 = 3 * 3 * 2

貢獻了3個0的因子

27 = 3 * 3 * 3

30/3+30/9+30/27所代表的,就是最終結果。

這是因爲:30/3把所有貢獻了0的因子都算了一次,9、18、27已經被算過一次了,但是9和18還有一個因子沒有算,27中還有兩個因子沒有算。

30/9則計算了一次9、18、27,但是27中還有一個因子沒有算。

30/27計算了一次27,至此,所有的因子都計算完畢。

答案就是 30/3+30/9+30/27=10+3+1=14


分析本題

n!中,結尾有多少個連續的0

不能像上題一樣,直接除以10……因爲10可以拆分成兩個因子,2和5。但是也不能除以2,因爲在任何情況下,2的個數都會多餘5的個數,所以,最終除以5就好啦!

100!中,結尾有多少個連續的0?

100/5 + 100/25 + 100/125 = 20 + 4 + 0 = 24

計算公式

發揮我少的可憐的數學功底,寫一個計算公式/(ㄒoㄒ)/~~

n!0=i=1log5(n)[n5i]

在代碼中,一定要注意溢出的問題,如下代碼(我的第一個代碼)就不能通過測試。因爲在n很大時,比如Integer.MAX_VALUE,i *= 5溢出了,i一直是小於等於n,所以是死循環!

    public static int trailingZeroes2(int n) {

        int rt = 0;
        for (int i = 5; i <= n; i *= 5) {
            rt += n / i;
        }

        return rt;
    }

解決方法,把n定義成long型。注意i也要定義成long型,否則在n很大時,主要是i * 5 > Integer.MAX_VALUE後會出錯。

    public int trailingZeroes(int n) {

        int rt = 0;
        long N = n;

        for (long i = 5; i <= N; i *= 5) {
            rt += N / i;
        }

        return rt;
    }

Fraction to Recurring Decimal

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.

If the fractional part is repeating, enclose the repeating part in parentheses.

For example,

  • Given numerator = 1, denominator = 2, return “0.5”.
  • Given numerator = 2, denominator = 1, return “2”.
  • Given numerator = 2, denominator = 3, return “0.(6)”.

Credits:
Special thanks to @Shangrila for adding this problem and creating all test cases.


  1. 首先判斷符號,使用Math.signum()。如果是正數,返回1;負數,返回-1;是0,返回0。

    Returns the signum function of the argument; zero if the argument is zero, 1.0f if the argument is greater than zero, -1.0f if the argument is less than zero.

  2. 考慮到溢出,輔助變量定義成long。這是因爲如果:

    numerator = Integer.MAX_VALUE; 
    denominator = Integer.MAX_VALUE - 1;

    那麼在numerator * 10 後,就溢出了。

  3. 要取絕對值,因爲 -2 % 3 = -2, -2 % -3 = -2

  4. 分析57,餘數分別是 5 1 3 2 6 4 5,到5處就出現了循環。因爲餘數必然在[0,7)範圍內,如果不能除盡,必然是無限循環小數。循環的位置,就是某餘數第一次出現的位置,至當前該餘數出現的位置(該餘數是所有餘數中,第一個出現2次的)。

          ·         ·
        0.7 1 4 2 8 5
        - - - - - - - 
    7 )5 0
        4 9
        - - - - - - - 
          1 0       
            7       
            - - - - -
            3 0     
            2 8     
            - - - - -
              2 0   
              1 4   
              - - - -
                6 0 
                5 6 
                - - -
                  4 0
                  3 5
                  - -
                    5
    

    如上圖所示(希望沒畫錯)。在程序中,就是用Map來表示,key是n/10,也就是整數部分除完後,剩下的餘數。餘數肯定比被除數小;value是key出現的位置。

    map中key和value出現的順序:

    key     value
     5        0
     1        1
     3        2
     2        3
     6        4
     4        5
    

    下一個n/10是5,map中存在,即可在0處插入“(”,在最後插入“)”。

    public String fractionToDecimal(int numerator, int denominator) {

        String sign = "";

        if (Math.signum(numerator) * Math.signum(denominator) < 0) {
            sign = "-";
        }

        long n = Math.abs(numerator);
        long d = Math.abs(denominator);

        String intPart = Math.abs(n / d) + "";

        // 如果整除,直接返回結果
        if (n % d == 0) {
            return sign + intPart;
        }

        // 計算小數部分
        n %= d;
        n *= 10;

        StringBuilder sb = new StringBuilder();
        Map<Long, Integer> mod = new HashMap<Long, Integer>();

        for (int i = 0; n != 0; i++) {

            long q = n / d;

            Integer start = mod.get(n / 10);

            if (start != null) {
                sb.insert(start, "(");
                sb.append(")");
                break;
            }

            sb.append(Math.abs(q));
            mod.put(n / 10, i);

            n %= d;
            n *= 10;
        }

        String fractionalPart = sb.toString();

        return sign + intPart + "." + fractionalPart;
    }

Integer to Roman

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.


羅馬數字的計數方法

基本字符 I V X L C D M
阿拉伯數字表示 1 5 10 50 100 500 1000
  1. 相同的數字連寫,所表示的數等於這些數字相加得到的數,如:Ⅲ = 3;
  2. 小的數字在大的數字的右邊,所表示的數等於這些數字相加得到的數, 如:Ⅷ = 8;Ⅻ = 12;
  3. 小的數字,(限於Ⅰ、X 和C)在大的數字的左邊,所表示的數等於大數減小數得到的數,如:Ⅳ= 4;Ⅸ= 9;
  4. 正常使用時,連寫的數字重複不得超過三次。(錶盤上的四點鐘“IIII”例外);
  5. 在一個數的上面畫一條橫線,表示這個數擴大1000倍。
    public String intToRoman(int num) {

        final int[] values = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5,
                4, 1 };

        final String[] symbol = { "M", "CM", "D", "CD", "C", "XC", "L", "XL",
                "X", "IX", "V", "IV", "I" };

        StringBuilder result = new StringBuilder();

        for (int i = 0; num > 0; i++) {

            int count = num / values[i];
            num %= values[i];

            for (; count > 0; count--) {
                result.append(symbol[i]);
            }
        }

        return new String(result);
    }

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.


這裏寫圖片描述

    public String multiply(String num1, String num2) {

        if (num1 == null || num2 == null) {
            return "";
        }

        int[] paper = new int[num1.length() + num2.length()];

        char[] _num1 = num1.toCharArray();
        char[] _num2 = num2.toCharArray();

        for (int i = 0; i < _num1.length; i++) {
            for (int j = 0; j < _num2.length; j++) {
                paper[paper.length - (i + j + 2)] += (_num1[i] - '0')
                        * (_num2[j] - '0');
            }
        }

        // add
        for (int i = 0; i < paper.length - 1; i++) {
            paper[i + 1] += paper[i] / 10;
            paper[i] %= 10;
        }

        String s = "";
        for (int i = paper.length - 1; i > 0; i--) {

            if ("" == s && paper[i] == 0) {
                continue;
            }
            s += paper[i];
        }

        s += paper[0];

        return s;
    }

    // can't be accepted in leetcode
    public String multiply2(String num1, String num2) {

        if (num1 == null || num2 == null) {
            return "";
        }

        BigInteger n1 = new BigInteger(num1);
        BigInteger n2 = new BigInteger(num2);

        return n1.multiply(n2).toString();
    }

Number of Digit One

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

Hint:

  1. Beware of overflow.

參考:http://blog.csdn.net/xudli/article/details/46798619

    public int countDigitOne(int n) {
        int ones = 0;
        for (long m = 1; m <= n; m *= 10) {
            long a = n / m, b = n % m;
            ones += (a + 8) / 10 * m;
            if (a % 10 == 1)
                ones += b + 1;
        }
        return ones;
    }

Palindrome Number

Determine whether an integer is a palindrome. Do this without extra space.

click to show spoilers.

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.


    public boolean isPalindrome(int x) {

        if (x < 0) {
            return false;
        }

        if (x >= 0 && x < 10) {
            return true;
        }

        int d = 1;
        while (x / d >= 10) {
            d *= 10;
        }

        while (x != 0) {

            if (x % 10 != x / d) {
                return false;
            }

            x = x % d / 10;
            d /= 100;
        }

        return true;
    }

Perfect Squares

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.


動態規劃,求解最優化問題,自底向上。

    public int numSquares(int n) {

        int[] dp = new int[n + 1];

        Arrays.fill(dp, Integer.MAX_VALUE);

        // 將所有平方數置1
        for (int i = 0; i * i <= n; i++) {
            dp[i * i] = 1;
        }

        for (int a = 1; a <= n; a++) {
            for (int b = 1; a + b * b <= n; b++) {
                // 取較小值,a + b * b也可能是平方數
                dp[a + b * b] = Math.min(dp[a] + 1, dp[a + b * b]);
            }
        }

        return dp[n];
    }

Permutation Sequence

The set [1,2,3,…,_n_] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.


首先想到的是遞歸,按照順序尋找字符串,然後計數,計算到第k個就是所求字符串。但是這樣太慢,在n=9,k很大時會超時。

然後根據規律來,我們發現當n=3時排列是3! = 6組,其中以“1”,“2”,“3”開頭的分別有2組。

以“1”開頭的排列中,第2位是“2”、“3”的分別有1組。

如果n=4呢?會發現以1開頭的排列有6組,其中以2爲第2位的排列有2組。

總結規律:第一位數字在數組中的序號肯定是:

k1/(n−1)!

k1=k

第二位數字在剩餘數組中的序號肯定是:

k2/(n−2)!

k2=k1

    public String getPermutation(int n, int k) {

        if (n <= 0 || k <= 0) {
            return "";
        }

        String result = "";

        List<Integer> list = new ArrayList<Integer>();
        int fact = 1;

        for (int i = 1; i <= n; i++) {
            list.add(i);
            fact *= i;
        }

        k--;

        for (int i = 0; i < n; i++) {
            fact /= (n - i);
            int index = k / fact;
            result += list.get(index);
            list.remove(index);
            k %= fact;
        }

        return result;
    }

Plus One

Given a non-negative number represented as an array of digits, plus one to the number.

The digits are stored such that the most significant digit is at the head of the list.


    public int[] plusOne(int[] digits) {

        if (digits == null || digits.length == 0) {
            return null;
        }

        int[] rt = new int[digits.length + 1];
        digits[digits.length - 1]++;

        for (int i = digits.length - 1; i >= 0; i--) {
            rt[i + 1] += digits[i];
            rt[i] += rt[i + 1] / 10;
            rt[i + 1] %= 10;
        }

        if (rt[0] == 0) {
            return Arrays.copyOfRange(rt, 1, rt.length);
        } else {
            return rt;
        }
    }

Power of Two

Given an integer, write a function to determine if it is a power of two.

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.


    public boolean isPowerOfTwo(int n) {

        if (n <= 0) {
            return false;
        }
        return (n & (n - 1)) == 0;
    }

Pow(x, n)

Implement pow(xn).


    public double myPow(double x, int n) {
        if (n < 0) {
            return 1 / pow(x, -n);
        } else {
            return pow(x, n);
        }
    }

    private double pow(double x, int n) {

        if (n == 0) {
            return 1;
        }

        double v = pow(x, n / 2);

        if (n % 2 == 0) {
            return v * v;
        } else {
            return v * v * x;
        }
    }
}

Rectangle Area

Find the total area covered by two rectilinear rectangles in a 2D plane.

Each rectangle is defined by its bottom left corner and top right corner as shown in the figure.

Rectangle Area

Assume that the total area is never beyond the maximum possible value of int.

Credits:
Special thanks to @mithmatt for adding this problem, creating the above image and all test cases.


題目要求的是兩個矩形總的面積,不是相交的面積……

  1. 不考慮兩個矩形相交,分別求出每個矩形的面積,相加
  2. 如果兩個矩形不相交,直接返回結果
  3. 如果兩個矩形相交,減去相交部分面積
    public int computeArea(int A, int B, int C, int D, int E, int F, int G,
            int H) {

        int area = (C - A) * (D - B) + (G - E) * (H - F);

        if (A >= G || B >= H || C <= E || D <= F) {
            return area;
        }

        int top = Math.min(D, H);
        int bottom = Math.max(B, F);
        int left = Math.max(A, E);
        int right = Math.min(C, G);

        return area - (top - bottom) * (right - left);

    }

Reverse Integer

Reverse digits of an integer.

Example1: x = 123, return 321
Example2: x = -123, return -321

click to show spoilers.

Have you thought about this?

Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!

If the integer’s last digit is 0, what should the output be? ie, cases such as 10, 100.

Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?

For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

Update (2014-11-10):
Test cases had been added to test the overflow behavior.


    public int reverse(int x) {

        if (x == Integer.MIN_VALUE) {
            return 0;
        }

        if (x < 0) {
            return -reverse(-x);
        }

        int rt = 0;

        do {

            // y * 10 + x % 10 > Integer.MAX_VALUE
            if (rt > (Integer.MAX_VALUE - x % 10) / 10) {
                return 0;
            }

            rt = rt * 10 + x % 10;
            x = x / 10;

        } while (x > 0);

        return rt;
    }

Roman to Integer

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.


羅馬數字的計數方法

基本字符 I V X L C D M
阿拉伯數字表示 1 5 10 50 100 500 1000
  1. 相同的數字連寫,所表示的數等於這些數字相加得到的數,如:Ⅲ = 3;
  2. 小的數字在大的數字的右邊,所表示的數等於這些數字相加得到的數, 如:Ⅷ = 8;Ⅻ = 12;
  3. 小的數字,(限於Ⅰ、X 和C)在大的數字的左邊,所表示的數等於大數減小數得到的數,如:Ⅳ= 4;Ⅸ= 9;
  4. 正常使用時,連寫的數字重複不得超過三次。(錶盤上的四點鐘“IIII”例外);
  5. 在一個數的上面畫一條橫線,表示這個數擴大1000倍。
    public String intToRoman(int num) {

        final int[] values = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5,
                4, 1 };

        final String[] symbol = { "M", "CM", "D", "CD", "C", "XC", "L", "XL",
                "X", "IX", "V", "IV", "I" };

        StringBuilder result = new StringBuilder();

        for (int i = 0; num > 0; i++) {

            int count = num / values[i];
            num %= values[i];

            for (; count > 0; count--) {
                result.append(symbol[i]);
            }
        }

        return new String(result);
    }

Sqrt(x)

Implement int sqrt(int x).

Compute and return the square root of x.


    public int mySqrt(int x) {

        // 首先對負數和0進行處理
        if (x < 0) {
            return -1;
        } else if (x == 0) {
            return 0;
        }

        int start = 1;
        int end = x;

        while (start < end) {

            // 不能直接相加除以2,因爲兩個數相加可能溢出
            int m = start + (end - start) / 2;

            // 不能用m^2,(m+1)^2,因爲可能溢出
            int m1 = x / m;
            int m2 = x / (m + 1);

            // m*2 == x
            if (m == m1) {
                return m;
            }

            // (m+1)^2 == x
            if (m + 1 == m2) {
                return m + 1;
            }

            // m*2 <= x && (m+1)^2 > x
            if (m < m1 && m + 1 > m2) {
                return m;
            }

            // m*2 > x
            if (m1 < m) {
                end = m;
            } else {
                // (m+1)^2 < x
                start = m + 1;
            }
        }

        return 1;
    }

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.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button  to reset your code definition.

spoilers alert… click to show requirements for atoi.

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.


  1. 無效的格式,如:”+-1234”, “+-c1234”;
  2. 有效的格式,如:”-123c4”, “+1234”;
  3. 數據溢出,如:”2147483648”;
  4. 注意字符串首尾的空格。
    public int myAtoi(String str) {

        if (str == null || str.length() == 0) {
            return 0;
        }

        char[] c = str.toCharArray();

        int i = 0, flag = 1, rt = 0;

        for (; i < c.length; i++) {
            if (c[i] == ' ') {
                continue;
            } else {
                break;
            }
        }

        if (c[i] == '+') {
            i++;
        } else if (c[i] == '-') {
            flag = -1;
            i++;
        }

        for (; i < c.length; i++) {

            if (c[i] > '9' || c[i] < '0') {
                break;
            }

            if (rt > Integer.MAX_VALUE / 10
                    || (rt == Integer.MAX_VALUE / 10 && (c[i] - '0') > Integer.MAX_VALUE % 10)) {
                return (flag == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }

            rt = rt * 10 + c[i] - '0';
        }

        return rt * flag;
    }

Ugly Number

Write a program to check whether a given number is an ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7.

Note that 1 is typically treated as an ugly number.

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.


    public boolean isUgly(int num) {

        if (num < 1) {
            return false;
        }

        while (num != 1) {
            if (num % 2 == 0) {
                num /= 2;
            } else if (num % 3 == 0) {
                num /= 3;
            } else if (num % 5 == 0) {
                num /= 5;
            } else {
                return false;
            }
        }

        return true;
    }

Ugly Number II

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number.

Hint:

  1. The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.
  2. An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
  3. The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3.
  4. Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).

Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.


維持一個數組,依次存入醜數序列。

    public int nthUglyNumber(int n) {

        int[] nums = new int[n];

        nums[0] = 1;

        int i = 0, j = 0, k = 0, t = 1;

        while (t < n) {
            int min = Math.min(Math.min(nums[i] * 2, nums[j] * 3), nums[k] * 5);

            nums[t++] = min;

            if (nums[i] * 2 == min) {
                i++;
            }

            if (nums[j] * 3 == min) {
                j++;
            }

            if (nums[k] * 5 == min) {
                k++;
            }
        }

        return nums[n - 1];
    }

Valid Number

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button  to reset your code definition.


    public boolean isNumber(String s) {

        if (s == null || s.length() == 0) {
            return false;
        }

        char[] chars = s.toCharArray();
        int start = 0, end = chars.length - 1;

        // 除去前後的空格
        while ((start < end) && chars[start] == ' ') {
            start++;
        }
        while ((start < end) && chars[end] == ' ') {
            end--;
        }

        // 因爲while的循環條件是start < end,s爲空格時,會剩下一個空格
        if (chars[start] == ' ') {
            return false;
        }

        boolean dot = false;
        boolean num = false;
        boolean ex = false;

        for (int i = start; i <= end; i++) {

            char c = chars[i];

            if (c >= '0' && c <= '9') {
                num = true;
            } else if (c == 'e') {
                if (ex)
                    return false;
                if (!num)
                    return false;

                ex = true;
                num = false;
                dot = false;
            } else if (c == '.') {
                if (dot) {
                    return false;
                }
                if (ex) {
                    return false;
                }
                dot = true;
            } else if (c == '+' || c == '-') {
                if (num || dot) {
                    return false;
                }
            } else {
                return false;
            }
        }

        return num;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章