幾個面試常考的問題

前言

最近正在緊鑼旗鼓的準(zhǔn)備面試,期間遇到了許多好精巧的算法問題。于是大致實現(xiàn)了下,做個筆記。

判斷一個數(shù)是否為2的冪

這個題有兩種解法,一個是常規(guī)的,思路如下:

不斷的將這個數(shù)除2,求得余數(shù)。當(dāng)余數(shù)為1的時候,判斷當(dāng)前除數(shù)和2的大小關(guān)系,如果大于2,則說明此數(shù)不是2的冪,如果小于2則說明此數(shù)為2的冪。

另外一個方法就比較hack了,思路如下:

如果一個數(shù)為2的冪,則二進制首位必為1,其余位為0.
將這個數(shù)減一,得到的數(shù)與該數(shù)相與,結(jié)果為0則說明此數(shù)為2的冪數(shù),否則不是。

代碼可以大致寫成這樣。

public boolean isPowerOf2(int number) {
        return ((number-1)&number)==0?true:false;
}

這樣是不是既高效又簡便呢?

不使用if, while, for,switch,goto等關(guān)鍵字實現(xiàn)100行代碼打印出1000個helloworld

按照常規(guī)理解,這是不可能的了。那么要怎么實現(xiàn)呢?

我個人倒是覺得繞開這些關(guān)鍵字倒是個不錯的方法,比如使用更底層的語言。高級語言之下不是還有諸如匯編語言,機器語言這些的嘛,雖然可讀性會很差,但是也不失為一個好辦法。

但是非得讓用某一個語言來實現(xiàn),要怎么做呢?

答案之一就是用遞歸來實現(xiàn)。且看下面的代碼。

# coding: utf8
number = 0

def p1():
    global number 
    number += 1
    print "Hello World"

def p2():
    p1()
    p1()

def p3():
    p2()
    p2()
    p2()

def p4():
    p3()
    p3()
    p3()
    p3()

def p5():
    p4()
    p4()
    p4()
    p4()
    p4()

def p6():
    p5()
    p5()
    p5()
    p5()
    p5()
    p5()

def p7():
    p6()
    p6()
    p6()
    p6()
    p6()
    p6()
    p6()
if __name__ == '__main__':
    p7()
    print "共執(zhí)行了{}次,得到了{}個Hello World!".format(number, number)

得到的結(jié)果呢?


獲取結(jié)果

這樣,使用遞歸的方式便可以實現(xiàn)100行以內(nèi)的代碼獲取到大于1000行Hello World!的輸出了。

不使用+實現(xiàn)一個加法函數(shù)

這就有點難為人了,反正我是怎么想也沒想出來。后來參考網(wǎng)上的思路,使用模擬與數(shù)字電路的方式可以實現(xiàn)。

原理就是:

兩個數(shù)先異或運算
兩個數(shù)相與的結(jié)果左移一位
遞歸判斷,獲取返回結(jié)果

使用代碼實現(xiàn)起來可能如下:

public static int addWithoutOperators(int number1, int number2) {
        // 如果有一個數(shù)為0,則直接返回另一個數(shù)
        if(number2 == 0)
            return number1;
        if(number1 == 0)
            return number2;
        // 先異或運算
        int sum = number1 ^ number2;
        //求出進位,這時對于01,10,00都是不產(chǎn)生進位的,只有11才會產(chǎn)生進位
        int carry = ( number1 & number2 ) << 1;
        return addWithoutOperators(sum, carry);
    }

運算測試


加法運算結(jié)果

不使用-實現(xiàn)減法函數(shù)

兩數(shù)相減,就是一個數(shù)加上另一個數(shù)的相反數(shù)唄。我們常規(guī)就是這么理解的,那么怎樣才能獲取一個數(shù)的相反數(shù)呢?

求相反數(shù)很簡單,直接取反加一即可。也就是


求正數(shù)的相反數(shù)

負數(shù)同樣適用。

那么利用這一點,就可以輕松的實現(xiàn)減法函數(shù)了。

public static int subtractWithoutOperators(int number1, int number2) {
        if(number1 == number2) 
            return 0;
        int reverse = addWithoutOperators(~number2, 1);
        return addWithoutOperators(number1, reverse);
    }

運算結(jié)果如下:


實現(xiàn)減法函數(shù)的結(jié)果

除此之外,還有一個直接操作二進制的方式,

int Subtract(int a, int b)
{
    while (b != 0) 
    {
        int sameBits = a & b;
        a ^= sameBits;
        b ^= sameBits;
        a |= b;
        b <<= 1;
    }

    return a;
}

還有其他的乘除運算的實現(xiàn)方法,詳情請參考下面的鏈接:
http://www.cppblog.com/qingbizhu/archive/2012/03/30/168148.html

實現(xiàn)BMP算法

求子字符串在字符串中第一次出現(xiàn)的位置,這倒是一個挺簡單的實現(xiàn),至于那個改進版的,我還不太理解,就不寫了。

/**
 * @Date 2017年3月5日
 *
 * @author 郭  璞
 *
 */
package interview;

/**
 * @author 郭 璞
 *
 *         關(guān)于字符串中字串位置的查找相關(guān)的幾個實現(xiàn)
 *
 */
public class StringPiexl {

    public static void main(String[] args) {
        String original = "hello world!";
        String substr = "llo";

        StringPiexl piexl = new StringPiexl();
        System.out.println(piexl.bmp(original, substr));

    }

    public int bmp(String original, String substr) {
        if (original.length() < substr.length())
            return -1;

        char[] originals = original.toCharArray();
        char[] substrs = substr.toCharArray();

        for (int outter = 0; outter < originals.length - substrs.length; outter++) {

            for (int inner = 0; inner < substrs.length;) {
                if (originals[outter++] == substrs[inner++]) {
                    if (inner == substrs.length - 1) {
                        return outter - inner;
                    }
                } else {
                    outter = outter - inner;
                    break;
                }
            }
        }
        return -1;

    }

}

運算結(jié)果如下:

2

打靶問題

打靶10次,得到90分的方式有幾種?
像這種問題還有很多,什么雞兔同籠啊,百錢白雞啊,都是類似的。

一方面我們可以采用枚舉法來暴力破解,另一方面就只能采用遞歸。兩者各有利弊吧,今天的這個打靶問題,我就用遞歸來實現(xiàn)一下。

/**
 * @Date 2017年3月3日
 *
 * @author 郭  璞
 *
 */
package interview;

/**
 * @author 郭 璞
 * 
 *         打靶的遞歸實現(xiàn)
 *
 */
public class ShootTest {

    /**
     * 設(shè)置為11位的數(shù)組是因為下邊按1開始到10來使用!
     */
    public static int[] record = new int[11];
    public static int totalMethods = 0;

    public static void main(String[] args) {
        shoot(90, 10);
        System.out.println("共有的可能的解法為:" + totalMethods);
    }

    public static void shoot(int score, int number) {
        // 此處score > number*10 可用90替代,但是根據(jù)不同的要求還需要硬編碼替換!
        if (score < 0 || score > number * 10) {
            return;
        }
        if (number == 1) {
            record[10-number] = score;
            print(record);
            totalMethods ++;
        }
        for (int index = 0; index <= 10; index++) {
            record[10-number] = index;
            shoot(score - index, number - 1);
        }
    }

    /**
     * @param record2
     * 打印的時候是按照第一槍到第number槍來計算的,因為要符合人類世界的從1開始的計算。
     */
    private static void print(int[] record2) {
        for (int index = 1; index < record2.length; index++) {
            System.out.print("\t" + record2[index]);
        }
        System.out.println("-----------------------------------");

    }

}

運算結(jié)果:


打靶問題結(jié)果

總結(jié)

好像面試的時候好多問題都是為了問題而問題,這樣的考察我覺得不是很好,畢竟實際中不會有這么偏門的問題吧。但是為了更好的充實自己,了解一下還是不錯的。

這篇文章就先這樣啦,以后再遇到這類問題,也許會更新一下,也會會另寫一篇。

如果看到了此文的你有類似的好的面試題的解法,也可以在下面留言評論,讓我們一起進步吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 歸去來兮。 1.1 說明 本篇為《挑戰(zhàn)程序設(shè)計競賽(第2版)》[http://www.ituring.com.cn...
    尤汐Yogy閱讀 14,892評論 0 160
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,673評論 18 399
  • 索引的實現(xiàn)方式 1、B+樹我們經(jīng)常聽到B+樹就是這個概念,用這個樹的目的和紅黑樹差不多,也是為了盡量保持樹的平衡,...
    大黃大黃大黃閱讀 2,449評論 1 14
  • 生活可以平淡如水,但也需色彩點綴。 我可以抱著貓咪睡覺,卻容不得狗狗在我面前嘚瑟。 我喜歡聽?wèi)雅f風(fēng),民謠,卻不喜歡...
    泡泡染閱讀 713評論 16 7
  • 在某一瞬間,想起紅樓夢,美好的姑娘和討厭的婆子,于是曹選擇寫死姑娘……似乎回不去了哈,我在心里無數(shù)遍地跟自己說。 ...
    寧波小娘在杭州閱讀 670評論 0 1

友情鏈接更多精彩內(nèi)容