LeetCode初級算法之字符串:7 整數反轉

整數反轉

題目地址:https://leetcode-cn.com/problems/reverse-integer/java

給出一個 32 位的有符號整數,你須要將這個整數中每位上的數字進行反轉。算法

示例 1:數組

輸入: 123
輸出: 321

示例 2:優化

輸入: -123
輸出: -321

示例 3:指針

輸入: 120
輸出: 21

注意:code

假設咱們的環境只能存儲得下 32 位的有符號整數,則其數值範圍爲 [−2^31, 2^31 − 1]。請根據這個假設,若是反轉後整數溢出那麼就返回 0。索引

解法一:暴力解法

主體leetcode

  1. 整數轉字符串字符串

  2. 字符串的反轉get

  3. 字符串轉整數

邊界

  • 數值溢出邊界:溢出返回0

細節

  • 首位不爲0
  • 符號處理
public int reverse(int x) {
	//1.整數轉字符串
    String str = "" + x;
    char[] s = str.toCharArray();
    //2.字符串的反轉
    int n = s.length;
    for(int i = 0; i < n/2; i++){
        char temp = s[i];
        s[i] = s[n-i-1];
        s[n-i-1] = temp;
    }
    //3.字符串轉整數 
    //Integer result = Integer.valueOf(String.valueOf(array));
    long value  = Long.valueOf(String.valueOf(array));
    boolean b = value > Integer.MAX_VALUE || value < Integer.MIN_VALUE;
    int result = b ? 0 : (int)value;
    return result;
}

在上述代碼中已經完成主體代碼以及反轉後的數值越出邊界的問題,首位不爲零問題:Integer將整數字符串轉整數時會自動去掉前面若是有高位的0。那麼還剩下符號處理整數x若是是-123,反轉字符串是"321-"確定是不能的。要把負號拿出來以後的數字參與主體過程,最後再把結果加上負號。

//拿走符號sign
int sign = x > 0 ? 1 : -1;
//剩下絕對值
x = x < 0 ? x * -1 : x;

讓處理以後的x參與主體代碼,最後返回值加上符號

return result * sign;

但上面拿絕對值的這個步驟是有問題的,由於最小值的絕對值是比最大值要大1的。當傳入的int x = Integer.MIN_VALUE時絕對值超過了int的範圍。所以在符號拿取以前先進行判斷,把極值(包括最大值)直接返回掉畢竟它們反轉以後數字大小必定是溢出不必通過主體三步以後在判斷是否返回0。

public int reverse(int x) {
    //極值篩掉
	if(x == Integer.MAX_VALUE || x == Integer.MIN_VALUE){
        return 0;
    }
    //符號處理
	int sign = x > 0 ? 1 : -1;
	x = x < 0 ? x * -1 : x;
	//1.整數轉字符串
    String str = "" + x;
    char[] s = str.toCharArray();
    //2.字符串的反轉
    int n = s.length;
    for(int i = 0; i < n/2; i++){
        char temp = s[i];
        s[i] = s[n-i-1];
        s[n-i-1] = temp;
    }
    //3.字符串轉整數 
    //Integer result = Integer.valueOf(String.valueOf(array));
    long value  = Long.valueOf(String.valueOf(s));
    boolean b = value > Integer.MAX_VALUE || value < Integer.MIN_VALUE;
    int result = b ? 0 : (int)value;
    //加上符號
    return result * sign;
}

時間複雜度O(n),空間複雜度O(n)

解法二:數學思惟

既然是把一個整數變成另一個整數面對這樣的問題的徹底能夠找到數學的方式,在數組裏咱們使用索引指針取各個值,在數字裏面咱們就能夠用除法和取模運算來獲取各個值。上面咱們數組或者字符串直接拼接各個字符。這裏咱們就累加拼接。效率提高一個次元。

public int reverse(int x) {
    //極值篩掉
	if(x == Integer.MAX_VALUE || x == Integer.MIN_VALUE){
        return 0;
    }
    int result = 0;//返回結果
	int last = 0;//末位
    while((last = x % 10) != x){
        result = result * 10 + last;
        x /= 10;
    }
    //添加最後一位判斷溢出
    long value = result;
    value = value * 10 + last;
    if(value > Integer.MAX_VALUE || value < Integer.MIN_VALUE){
        return 0;
    }else{
        result = (int)value;
    }
    return result;
}

時間複雜度O(n),空間複雜度O(1)

總結

整體上是兩種思路但能夠優化的點還有一些好比個位判斷直接返回等等,這裏主要體會的是關於數字處理的相關算法都是能夠採用數學方式,它是遠遠比操做字符效率要高。第二就是關於實現主體與細節、邊界的一個劃分,儘可能下降耦合性。

相關文章
相關標籤/搜索