LeetCode 算法日常

解題思路來源于網絡和 awesome-java-leetcode
本菜鳥以小白的眼光去解釋大神的思路。

Easy

1.Two Sum

Given an array of integers, return indices(index 的復數) of the two numbers such that they add up to a specific(具體的、特定的) target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

題意為:給定一個整數數組,從中找到兩個數字使它們相加等于一個值,最后得到兩個數字在數組中的下標。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int length = nums.length;
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < length; i++){
             // 如果map存在和當前數相加等于目標值的數,說明這兩個數滿足了條件
            if(map.containsKey(nums[i])){
                // 取出該數在 map 中的下標,同時也是它在 nums 中的下標,因為下文放入了
                // 另外取出當前循環的值的下標,因為該下標表示的值滿足條件
                return new int[]{map.get(nums[i]),i};
            }
            // map 儲存目標減去數組中的值
            map.put(target - nums[i],i);
        }
        return null;
    }
}

7.Reverse Integer

Given a 32-bit signed integer, reverse digits of an integer.

Example 1:

Input: 123
Output:  321

Example 2:

Input: -123
Output: -321

Example 3:

Input: 120
Output: 21

Note:
Assume we are dealing with an environment which could only hold integers within the 32-bit signed integer range. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

題意為:給定一個32位整型數,返回它的逆序整型數。Note:當它的逆序整型數溢出的話,那么就返回 0。

思路 0:

class Solution {
    public int reverse(int x) {
        // 先用一個long類型來保存數據
        long r = 0;
        while(x != 0){
            // 第一次循環:取 x 的最小位并賦值給 r,比如 123 先取余數 3
            // 第二次循環:讓上次取的余數*10變為首位,當前 x=12 因為x/=10并且x是整數類型,再次取余數 2
            // 循環提升末位,并不斷添加最小位
            r = r * 10 + x % 10;
            x /= 10;
        }
        // 判斷如果范圍溢出返回0
        if(r < Integer.MIN_VALUE || r > Integer.MAX_VALUE){
            return 0;
        }else{
            return (int)r;
        }
    }
}

簡化后寫法:

class Solution {
    public int reverse(int x) {
        long res = 0;
        for(; x != 0; x /= 10){
            res = res*10 + x%10;
        }
        return res < Integer.MIN_VALUE || res > Integer.MAX_VALUE ? 0 : (int)res;
    }
}

9.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.

題意為:判斷一個有符號整型數是否是回文,也就是逆序過來的整數和原整數相同。負整數肯定不是,逆序過后符號放后了。

解 0:

class Solution {
    // 沒什么好說的,把整數倒過來判定
    public boolean isPalindrome(int x) {
        if(x < 0) return false;
        int num = 0;
        int copyX = x;
        while(copyX > 0){
            num = num * 10 + copyX % 10;
            copyX/=10;
        }
        return num == x;
    }
}

解 1:

class Solution {
    public boolean isPalindrome(int x) {
        // 循環一半和不判定10的倍數
        if (x < 0 || (x != 0 && x % 10 == 0)) return false;
        int halfReverseX = 0;
        while (x > halfReverseX) {
            halfReverseX = halfReverseX * 10 + x % 10;
            x /= 10;
        }
        return halfReverseX == x || halfReverseX / 10 == x;
    }
}

13. Roman to Integer

Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.

題意為:給定一個羅馬數字,轉換為整數 Integer。
范圍為 1 - 3999.

百度百科羅馬數字介紹:
羅馬數字是阿拉伯數字傳入之前使用的一種數碼。羅馬數字采用七個羅馬字母作數字、即Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。記數的方法:

  • 相同的數字連寫,所表示的數等于這些數字相加得到的數,如 Ⅲ=3;
  • 小的數字在大的數字的右邊,所表示的數等于這些數字相加得到的數,如 Ⅷ=8、Ⅻ=12;
  • 小的數字(限于 Ⅰ、X 和 C)在大的數字的左邊,所表示的數等于大數減小數得到的數,如 Ⅳ=4、Ⅸ=9;
  • 在一個數的上面畫一條橫線,表示這個數增值 1,000 倍,如
image

等于5000。

class Solution {
    public int romanToInt(String s) {
        // 先把所有羅馬英文字母添加到Map
        Map<Character,Integer> map = new HashMap<>();
        map.put('I',1);
        map.put('V',5);
        map.put('X',10);
        map.put('L',50);
        map.put('C',100);
        map.put('D',500);
        map.put('M',1000);
        int length = s.length();
        int sum = map.get(s.charAt(length - 1));
        // 拿最后一個字母跟前一個相比如果小就需要減,否則加
        for(int i = length - 2;i >= 0; i--){
            if(map.get(s.charAt(i)) < map.get(s.charAt(i + 1))){
                sum -= map.get(s.charAt(i));
            }else{
                sum += map.get(s.charAt(i));
            }
        }
        return sum;
    }
}

14. Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.

題意為:給定一個字符串數組,得出數組中這些字符串的公共開頭字符串。比如 "leeta" 和 "leetb" 的公共開頭為 "leet"。

解題思路 0:

public String longestCommonPrefix(String[] strs) {
    if (strs.length == 0) return ""; 
    String prefix = strs[0];
    // 遍歷字符數組,用來跟首個元素作對比
    for (int i = 1; i < strs.length; i++)
        // 因為 prefix 就是首個字符串,所以把首個排除
        while (strs[i].indexOf(prefix) != 0) {
            // 如果后面的字符串不是以 prefix 開頭的,就減小 prefix 的長度
            prefix = prefix.substring(0, prefix.length() - 1);
            // 如果最后沒有公共字符串,返回 ""
            if (prefix.isEmpty()) return "";
        }        
    return prefix;
}

解題思路 1:
出最短的那個字符串的長度minLen,然后在0...minLen的范圍比較所有字符串,如果比較到有不同的字符,那么直接返回當前索引長度的字符串即可,否則最后返回最短的字符串即可。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        int len = strs.length;
        if (len == 0) return "";
        int minLen = 0x7fffffff; // 0x7FFFFFFF 是long int的最大值
        for (String str : strs) minLen = Math.min(minLen, str.length());
        for (int j = 0; j < minLen; ++j)
            for (int i = 1; i < len; ++i)
                if (strs[0].charAt(j) != strs[i].charAt(j))
                    return strs[0].substring(0, j);
        return strs[0].substring(0, minLen);
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容