Java崗開發3年,公司臨時抽查算法,離職後這幾題我記一輩子

前幾天我們公司做了一件蠢事,非常非常愚蠢的事情。我原以爲從學校出來之後,除了找工作有測試外,不會有任何與考試有關的事兒。

 

但是,天有不測風雲,公司技術總監、人事總監兩位大佬突然降臨到我們事業線,叫上我老大,給我們組織了一場別開生面的“考試”。

那是一個風和日麗的下午,我翹着二郎腿,左手端着一杯卡布奇諾,右手抓着我的羅技鼠標,滾動着輪軸,穿梭在頭條熱點之間。

“淡黃的長裙~蓬鬆的頭髮~”

“WC,見證歷史,今年高考推遲了一個月,當年我要是碰上這種事,我豈不分分鐘985?”

同事:“這就是你考不上本科的原因?”

我:“呃~”

“WC,阿水水這是要去滔博嗎?”

同事:“這跟你考不上本科有什麼關係?”

我:“喂喂?”

 

這時,一位從沒見過的中年地中海出現在我的視線裏:“各位,注意一下,爲了考察大家的編程能力,5分鐘之後有一場測試,把自己的代碼保存好後,到大會議室集合。”

...

同事甲:“這不是總部來的技術總監嗎?”

同事乙:“WC,第一次看到大佬。”

我:“你們難道沒有聽到要測試嗎?”

...

後來,我們就不明不白的進行了一場測試,當我一片空白的試卷交上去,把一片空白的腦子帶出來,聽着同事們談論着測試答案。

同事告訴我,這份算法題來自百度,並給了我一份文件。

文件具體內容如下:

1、度度熊想去商場買一頂帽子,商場裏有 N 頂帽子,有些帽子的價格可能相同。度度熊想買一頂價格第三便宜的帽子,問第三便宜的帽子價格是多少?

 

輸入描述:

首先輸入一個正整數 N(N <= 50),接下來輸入 N 個數表示每頂帽子的價格(價格均是正整數,且小於等於 1000)

輸出描述:

如果存在第三便宜的帽子,請輸出這個價格是多少,否則輸出-1

輸入例子 1:

10

10 10 10 10 20 20 30 30 40 40

輸出例子 1:

30

解答:

/*簡單,時間複雜度也低*/
#include<iostream>
using namespace std;int main(){
int n,t=0,syn=0;
int price[1000]={0};
cin>>n;
while(n--){
cin>>t;
price[t]=1;
}
t=0;
for(int i=0;i<1000;i++){
if(price[t]&&syn<3)
syn++;
if(syn==3)
break;
 t++;
}
syn==3?cout<<t:cout<<-1;
}

 

2、一個數軸上共有 N 個點,第一個點的座標是度度熊現在位置,第 N-1 個點是度度熊的家。現在他需要依次的從 0 號座標走到 N-1 號座標。

但是除了 0 號座標和 N-1 號座標,他可以在其餘的 N-2 個座標中選出一個點,並直接將這個點忽略掉,問度度熊回家至少走多少距離?

 

解答:

從 N-2 個座標中選出一個點,並直接將這個點忽略掉。直接忽略一個點只會直接影響到,這個節點前後節點的距離。這個 影響的距離我們暫且命名爲優化距離,將所有節點按順序組成三個節點的集合,通過這種方式只需要通過一次循環便能得到結果。

優化距離越大說明如果去掉這個集合的中點元素將會使得總距離越短,下面上代碼。

import java.util.Scanner;


public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int length = scanner.nextInt();
        int[] arrays = new int[length];

        for (int i = 0; i < length; i++) {
            arrays[i] = scanner.nextInt();
        }

        /**
        * sum 總距離
        * repetition 三個節點 中被重複計算的總距離
        * select 優化距離最大的 三個節點兩兩相加的距離
        * add 三個結尾距離爲 max 中 頭尾節點的距離
        * last 最後三個節點中 尾距離沒有被計算兩次 需要加上
        * optimizeDistance 優化距離
        */
        int sum = 0,int repetition = 0,int select = 0,int add = 0,int last = 0,int optimizeDistance = 0;

        for (int i = 0; i <= (arrays.length - 3); i++) {
            int begin = arrays[i];
            int mid = arrays[i + 1];
            int end = arrays[i + 2];

            //三個點之間的距離
            int threePointDistance = Math.abs(mid - begin) +
                Math.abs(end - mid);

            //兩個點之間的距離 即被多次計算待會需要減掉的距離
            int twoPointDistance = Math.abs(end - mid);
            int contrast = threePointDistance - Math.abs(begin - end);
            repetition += twoPointDistance;
            sum += threePointDistance;
            last = twoPointDistance;

            if (contrast > optimizeDistance) {
                optimizeDistance = contrast;
                select = threePointDistance;
                add = Math.abs(end - begin);
            }
        }

        System.out.println((sum - select + last) - repetition + add);
    }
}

3、度度熊最近對全排列特別感興趣,對於 1 到 n 的一個排列,度度熊發現可以在中間根據大小關係插入合適的大於和小於符號(即 '>' 和 '<' )使其成爲一個合法的不等式數列。

但是現在度度熊手中只有 k 個小於符號即('<'')和 n-k-1 個大於符號(即'>'),度度熊想知道對於 1 至n 任意的排列中有多少個排列可以使用這些符號使其爲合法的不等式數列。

 

解答:

dp[i][j] = (dp[i - 1][j - 1] * (i - j) + dp[i - 1][j] * (j + 1)) % 2017;

dp[i][j]表示有 i 個數字及 j 個小於號所能組成的數量(大於號數量當然是 i - j - 1 次,後面需要使用)

而加入第 i + 1 個數字時,分以下四種情況:

  1. 如果將 i+1 插入當前序列的開頭,即有了 1<2,加入後成爲 3>1<2,會發現等於同時加入了一個大於號!(此時可以無視 1 與 2 之間的關係,因爲 i+1>i)
  2. 如果將 i+1 插入當前序列末尾,即 1<2 變成了 1<2<3,會發現等於同時加入了一個小於號! (此時可以無視 1 與 2 之間的關係,因爲 i+1>i)
  3. 如果將i+1加入一個小於號之間,即已經有 1<2了,向中間加入3,會發現變成了1<3>2,等於同時加入了一個大於號!
  4. 如果將 i+1 加入一個大於號中間,即有了 2>1,變成了 2<3>1,等於同時加入了一個小於號!

綜上所述,dp[i][j]等於以上四種情況之和:

dp[i - 1][j] 將 i 加在開頭等於加入一個大於號,即要求 i-1 個數時已經有了 j 個小於號;

dp[i - 1][j - 1] 將 i 加在末尾等於加入一個小於號,即要求 i-1 個數時已經有了 j-1 個小於號;

dp[i - 1][j] * j 將 i 加在任意一個小於號之間,等於加入了一個大於號,即要求 i-1 個數時已經有了 j 個小於號,每個小於號都可以進行這樣的一次插入;

dp[i - 1][j - 1] * (i- j - 1) 將 i 加載任意一個大於號之間,等於加入了一個小於號,即要求i-1 個數時有了 j-1 個小於號;

而此時共有(i - 1) - (j - 1)- 1 個大於號,每個大於號都要進行一次這樣的操作合併同類項即爲dp[i][j] = (dp[i - 1][j - 1] * (i - j) + dp[i - 1][j] * (j + 1))。

最後要記得取模。

......

由於篇幅原因,我就不一一給大家展示了,需要文件的朋友可以來私信我。

由於在準備面試,以前收集的Java進階寶典《Java核心知識點整理.pdf》,全文覆蓋了JVM、鎖、高併發、反射、mybatis、Spring原理、微服務、Zookeeper、數據庫、數據結構等等內容,獲取方式: 評論區獲取!

於是,我被老大叫去辦公室喝茶,然後,就離職了。

OS:你TM裁員就裁員,突擊測試算怎麼回事?


這段時間,我就是待就業狀態,網上找了一些算法和安卓有關的課程(沒錯,我轉安卓了,以後有問題可以一起探討探討)

幫忙宣傳一下,這個課程的具體內容:

JAVA容器

 

 

圖論

 

算法

 

還有他們所錄下的視頻文件,報了名後有以前的所有錄播視頻,我先看着,更詳細和更新的我等着看直播了,反正是終身可看的。

 

 

 

 

聽說這些視頻可以分享一些出來的,需要的可以私信我回復【資料】獲取領取方式。

由於在準備面試,以前收集的Java進階寶典《Java核心知識點整理.pdf》,全文覆蓋了JVM、鎖、高併發、反射、mybatis、Spring原理、微服務、Zookeeper、數據庫、數據結構等等內容,獲取方式:評論區獲取!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章