Leetcode-Problem:Reverse Integer

URNOTJANET發表於2018-02-25

好久沒練手了被卡在了這個題上,實在不應該...

不過分析的話這道題也是一個比較基礎的好題,特別是邊界條件判斷這方面。

題目描述:給定一個32位的帶符號整數,將其進行翻轉

連結:https://leetcode.com/problems/reverse-integer/description/

該問題需要考慮的點有:

1. 正負號

2. 尾數為零

3. 範圍(only hold integers within the 32-bit signed integer range)

該問題涉及到的考點(就當是考點)

1. integer 和 char 的相互轉換

2. 邊界條件涉及到的溢位問題【這個在除錯裡最慘...】

3. 在reverse的過程中,有負號和沒有負號的整數起始範圍不一

我的解決思路如下:

1)integer 轉 char 在C裡有sprintf 和 itoa, 但考慮到itoa並不是標準庫函式,可能會因為編譯情況不一存在問題,所以採用sprintf

該函式定義:

int sprintf( char *buffer, const char *format [, argument,…] );

將要轉換的引數列印到指定的buffer裡

e.g. sprintf(tmp,"%d",x);

將int的x 列印到tmp指向的陣列中

2)char 轉 integer在C中有標準庫函式atoi,直接呼叫即可。

3)正負號判定及尾數零

我在這裡對尾數零的情況解決的比較簡單粗暴,直接刪掉不要,從尾部開始,遇0則刪

正負號判斷就是看首部是否為"-",還比較簡單

4)邊界範圍判斷

32位整數最大是2147483647,直接判定是否有大於這個值就好。但這裡涉及到一個問題就是,在判定之前,我們已經將int轉為char 了,如果char 轉回來呢?當然這裡就很容易會因為reverse的緣故有溢位,就比較麻煩。

所以一個解決方案是將2147483647轉為str,然後strcmp:先看長度再比較每一位的ASCII

大概的解決思路就是這樣

我的思路不是最優的,如果存在什麼優化問題還請各位多多指點


C程式碼如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	char tmp[64];
	char* res;
	int flag = 0;
	int x,m;

	scanf("%d",&x);
	
	sprintf(tmp,"%d",x);
	int n = strlen(tmp);
	res = (char*)malloc(n*sizeof(char));
	for(int j=n; j>1; j--){
		if(tmp[j-1] != '0')break;
		n--;
	}

	if(tmp[0] == '-'){
		res[0] = tmp[0];
		for (int i = 1; i < n; ++i){
			res[i] = tmp[n-i];
		}
	}
	else{
		for(int i = 0; i < n; ++i){
			res[i] = tmp[n-i-1];
		}
	}
	int reverse;
	char* cmp = "2147483647";
	char* res1 = (char*)malloc(n*sizeof(char));
	if(res[0] == '-'){
		for(int j=0; j<n-1; j++){
			res1[j] = res[j+1];
		}
		res1[n-1] = '\0';
	}
	else{
		res1 = res;
	}

	if(strlen(res1)>strlen(cmp)){
		//printf("bigger\n");
		reverse = 0;
	}
	if(strlen(res1)<strlen(cmp)){
		//printf("lower\n");
		reverse = atoi(res);
	}
	if(strlen(res1) == strlen(cmp)){
		if(strcmp(res1,cmp)>0){
			//printf("big\n");
			reverse = 0;
		}
		else{
			reverse = atoi(res);
		}
	}
	//printf("%d\n", reverse);
	return 0;
}
複製程式碼


在discuss上找到一個短小精悍的解法,看來是我想的有點多....其實範圍可以縮小為int的問題,程式碼如下

int res = 0;
        while (x) {
            int temp = res * 10 + x % 10;
            if (temp / 10 != res)
                return 0;
            res = temp;
            x /= 10;
       }
return res;
複製程式碼

檢查overflow的精髓在於if中,如果temp存在overflow,那麼temp / 10 和res的結果一定不一樣

程式碼來源如下:

leetcode.com/problems/re…

另外學到的一點是,對於overflow 的處理,在C中其實是按照一個迴圈來的,比如說2147483648比最大上限2147483647多一個數,輸出的時候其實是-2147483648(感覺是個迴圈列表)



相關文章