某公司 幾個算法題(面試階段結束再公佈公司名稱)

 

1、
計算兩個日期之間相隔天數(等價於:知道之前某個日期是星期幾,問現在星期幾)
涉及知識:判斷閏年,月份用數組打表保存,根據閏年判斷2月天數
cpp代碼如下,頭文件自寫:這是1971年1月1日星期四,求當天星期幾的程序

bool is_r(int n) {
    if((n%400 == 0) || (n%4 == 0 && n%100 != 0)) return true;
    else return false;
}

int main() {
    int ny = 2020, nm = 4, nd = 23;

    int m[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int cnt = 0;
    int ans = 4;
    for(int i = 1971; i <= ny-1; ++i) {
        if(is_r(i)) {
            cnt += 366;
            //cout << "ÈòÄê " << i << endl;
        }
        else cnt += 365;
    }
    int t = 0;
    if(is_r(ny)) t = 1;
    for(int i = 1; i <= nm-1; ++i) {
        if(i == 2) cnt += (t + m[i]);
        else cnt += m[i];
    }
    cnt += nd;

    ans += cnt;
    ans = ans % 7;
    if(ans == 0) ans = 7;

    printf("%d", ans);
    return 0;
}

 

2、
10億(可以替換成n)個數,內存存不下,要找最大的k個數(k不大),怎麼找?複雜度怎麼樣?
建立k個結點的小頂堆,每次讀取到內存一些數,然後讀取每個數,跟堆頂比較是否需要替換,然後調整堆
最壞複雜度: O( 10億*k ) 這是原來的數列是遞增的情況下。

 

 

3、有一隻股票每一天有一個價格,問哪天買入哪天賣出獲利最大?
這個題以不同形式考到過兩次,這樣理解:股票的若干天價格看作一個數列,第i天買入 第j天賣出,條件是i<j,所以問題轉化爲對於確定的某一天 j(賣出),需要找到 數組數值最小的 i 這一天
解法:從左往右遍歷數組,用一個變量保存前面遍歷過的數的最小值, 沒遍歷到當前數,用當前數減去保存的最小值,每次更新這個差值。
 

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;

int main() {
    int a[10] ={9,0,-1,8,19,-7};
    int len = 6;

    int t = a[0];
    int ans = -INF;
    for(int i = 0; i < len; ++i) {
        ans = max(ans, a[i] - t);
        t = min(t, a[i]);
    }
    cout << ans;
    return 0;
}


4、
數組按絕對值大小進行排序,歸併排序,正負數絕對值相同時,先後順序隨意
 

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int a[10] = {-9, -7, -6, 0, 3, 8, 20};
int len = 7;

int abs_(int a) {
    return (a >= 0 ? a : (-1*a));
}

void mergsort(int l, int r) {
    if(l > r) return;
    if(l == r) return;
    int mid = (l + r) / 2;
    mergsort(l, mid);
    mergsort(mid+1, r);

    vector<int> tmp;
    int i = l, j = mid+1;
    while(i <= mid && j <= r) {
        if(abs_(a[i]) < abs_(a[j])) {
            tmp.push_back(a[i]);
            ++i;
        }
        else {
            tmp.push_back(a[j]);
            ++j;
        }
    }
    while(i <= mid) {
        tmp.push_back(a[i]);
        ++i;
    }
    while(j <= r) {
        tmp.push_back(a[j]);
        ++j;
    }
    int t = 0;
    for(int i = l; i <= r; ++i) {
        a[i] = tmp[t++];
    }
}

int main() {
    mergsort(0, len-1);
    for(int i = 0; i < len; ++i) {
        cout << a[i] << " ";
    }
    return 0;
}

5、
n個數,找出最大值最小值,不超過 n*1.5 次比較
開始以爲找最大n次,找最小n次,結果是要求找出兩個來比較次數一共不能超過上述比較次數
開始沒想出來,先說了別的,後來再問想出來了,這個 1.5 中的 .5 給我啓發了,而且是最大最小兩個極端,想到了對半分,該怎麼分呢,在比較的過程中,有的一些值不可能是最大或者最小的候選,
所以我想到了首先相鄰兩個數得到大小,這是 0.5*n次比較,然後大的比較得到最大值,小的比較得到最小值,分別比較 0.5*n次,如果n是奇數這種細節,也不妨礙解題了;

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