面試官,求求你不要問我這麼簡單但又刁難的算法題了

有時候面試官每每會問咱們一些簡單,但又刁難的問題,主要是看看你對問題的處理思路。若是你沒接觸過這些問題,可能一時之間還真不知道怎麼處理才比較好,這種題更重要的是一種思惟的散發吧,今天就來分享幾道題面試中遇到的算法題(固然,不是我本身遇到過,是別人遇到過,我挑選出來的)面試

案例1

題目描述:求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。算法

我去,求和竟然不讓用乘除法,也不許咱們用循環,若是單獨這兩個限制的話還好,咱們還能夠用地遞歸,例如:數據結構

int f(int n){
    if(n == 0){
        return n;
    }else{
        return f(n-1) + n;
    }
}

而後 if, else, case 等各類關鍵字也不給用,想着那我用三元運算符(A?B:C),而後這種具備判斷語句的三元運算符也不給用,我去,這也太刁難了吧(固然,大佬直接秒殺的能夠飄過)。函數

這道題確定是必須用遞歸來解決的,而這遞歸的核心就是須要判斷一下遞歸條件是否結束了,然而題目不許咱們使用條件判斷語句。那咱們該怎麼辦呢?你們能夠散發思惟想一下哦。工具

其實咱們能夠下面這樣的語句來代替 A?B:C 這樣具備判斷能力的三元運算符開發工具

n != 0 && (f(n-1) + n)  != 0;

這個 && 邏輯判斷符的做用就是:若是 n != 0 成立的話,那麼邏輯判斷符後面的判斷語句 (f(n-1) + n ) != 0 也會執行,若是 n != 0 不成立的話,那麼後面的判斷語句 ((f(n-1) + n)) != 0 就不會執行,經過這種方法,就能夠達到咱們遞歸結束條件判斷的目的了。code

這裏說明一下,(f(n-1) + n) != 0 這條判斷語句是沒有任意其餘含義的,咱們的目的是爲了執行 f(n-1)+n,之因此加上個 != 0 的判斷,是由於邏輯判斷符號 && 只支持 boolean 類型,不支持 int 類型。視頻

最後的代碼以下blog

public int f(int n) {
        int sum = n;
        boolean t = (n != 0) && (sum += f(n - 1))!= 0;
        return sum;
    }

若是你作過這種類型的題,可能就會以爲很簡單了,若是沒作過,可能就須要思考一下,不過,日後你就能夠直接秒殺了。遞歸

案例 2

題目描述:寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。

我去,求和不許加減乘除!面試官,能不能別這麼任性,好好的加減乘除竟然不給用。

不過我相信你們第一時間都能想到用位運算來解決,可能在大學期間學過電路相關知識的一下就能把代碼寫出來了,不過有些人也能多是一個位一個位來處理的。例如我先處理第一個位(這裏指的是二進制位哈),看看有沒進位,而後處理第二個位,若是第一個位有進位就加到第二個位來,而後處理第三個位.....

若是你是這種方法處理的,那麼恭喜你,看完這道題你能有所收穫。實際上上面那種解法也能夠,只是太複雜了,可能各類判斷。其實這道題能夠這樣解:這裏爲了方便講解,我先給出代碼,再給出具體的講解,你看完代碼再來看講解可能更好理解

public int Add(int num1,int num2) {
        int tmp = 0;
        while(num1 != 0){
            tmp = num1 ^ num2;
            num1 = (num1 & num2) << 1;
            num2 = tmp;
        }
        return num2;
    }

你們想一個問題,若是咱們把兩個數進行異或,例如num1 = 101, num2 = 001,作異或運算:tmp = num1 ^ num2,結果是 tmp = 100。那麼此時獲得的結果 tmp 其實就是兩個數(num1,num2)各個二進制位上相加,不算進位的結果。而 num1 = (num1 & num2) << 1 的結果就是兩個數相加時那些須要進位的二進制位。例如 (101 & 001)<< 1 = 010,那麼兩個數第一位相加須要進位,咱們須要把進的那一位最後加到第二位上去。

好像有點繞,,你們能夠動手試一下哈,說白就是 a + b = a ^ b + (a & b) << 1。

代碼中,若是 num1 == 0 的話,表明沒有進位了,此時就能夠退出循環了。

對於不多用位運算的人來講可能有點懵,那麼我建議能夠多看幾遍,而後一遍動手模擬哈。之後遇到這種題就能夠直接秒殺了。

案例3

在這裏我先聲明一下,案例3 也不算一道刁難題,只是我來考考大家而已,你們看到題目以後能夠本身想一下哈,看了答案不能打我哈。

題目描述:實現兩個整數的相乘,不能使用乘法運算符和循環

各位老哥能夠想一下哈。

這道題可能不少人都想到用遞歸了,好像我說的大部分算法題,都會用到遞歸,因此說你不懂遞歸的話,看個人公衆號就好了,不懂也得變懂了是否是。代碼以下:

int mul(int a, int b){
    if (a == 0 || b == 0)
        return 0;
    if (b == 1)
        return a;
    if (a == 1)
        return b;
    return a + mul(a, b - 1);
}
int mult(int a,int b){
    // 這裏咱們取 b 的絕對值
    int sum = mul(a, abs(b));
    return (b<0)?(-sum):sum;
}

你是否是這樣作的呢?其實,咱們還有更好的方法哦,以下

我去,不能使用乘法,又沒說不能使用除法,那我用除法來代替乘法就得了,例如 a 乘以 b 就至關於 a 除以 b 分之一。代碼以下:

int mult2 (int a,int b){
    return b != 0 ? (int)(a / (1.0 / b) + 0.99 ): 0;
}

這裏須要 int 進行轉化類型,而且除法可能會致使後面尾數的丟失,因此我補了個 0.99。注意,進行 int 類型轉化時,不是四捨五入的哈,二手小於 1 就行當作 0 處理。固然,我這裏用的是 Java 語言,其餘語言本身看狀況處理。

總結

今天的幾道題,更多的是一種投機取巧吧,不過看你看到一到陌生的題目時,你會如何處理,點子多很少,這個仍是挺重要滴,而多看一些點子,慢慢着你的點子也會變多了。

若是你以爲這篇內容對你挺有啓發,爲了讓更多的人看到這篇文章:不妨

一、點贊,讓更多的人也能看到這篇內容(收藏不點贊,都是耍流氓 -_-)

二、關注我和專欄,讓咱們成爲長期關係

三、關注公衆號「苦逼的碼農」,主要寫算法、計算機基礎之類的文章,裏面已有100多篇原創文章

公衆號主頁
大部分的數據結構與算法文章被各類公衆號轉載相信必定能讓你有所收穫

我也分享了不少視頻、書籍的資源,以及開發工具,歡迎各位的關注個人公衆號:苦逼的碼農,第一時間閱讀個人文章。

相關文章
相關標籤/搜索