2018今日頭條秋招 筆試 (2017/09/10)

20170910 頭條筆試

算法崗


【改錯題】

二分查找
http://blog.csdn.net/v_july_v/article/details/7093204

//首先要把握下面幾個要點:
//right=n-1 => while(left <= right) => right=middle-1;
//right=n   => while(left <  right) => right=middle;
//middle的計算不能寫在while循環外,否則無法得到更新。
int binary_search(int array[],int n,int value)
{
    int left=0;
    int right=n-1;
    //如果這裏是int right = n 的話,那麼下面有兩處地方需要修改,以保證一一對應:
    //1、下面循環的條件則是while(left < right)
    //2、循環內當array[middle]>value 的時候,right = mid

    while (left<=right)         //循環條件,適時而變
    {
        int middle=left + ((right-left)>>1);  //防止溢出,移位也更高效。同時,每次循環都需要更新。

        if (array[middle]>value)
        {
            right =middle-1;   //right賦值,適時而變
        } 
        else if(array[middle]<value)
        {
            left=middle+1;
        }
        else
            return middle;  
        //可能會有讀者認爲剛開始時就要判斷相等,但畢竟數組中不相等的情況更多
        //如果每次循環都判斷一下是否相等,將耗費時間
    }
    return -1;
}

題目沒有全部記得,循環體基本上按照上述思路改的。然後題目裏還說了如果有多個相同元素,取最後一個,所以加了一段:

int len = data.size();//慘了慘了 不該寫這句的
while(mid+1<len && data[mid+1] == target)
    mid++

題目裏面有直接將vector的size方法直接賦給int類型的變量,其實這樣是會引起warning的,因爲size方法返回的其實是size_type類型,並不是int類型。在不同的機器上可能會出現不同結果。雖然一般都能僥倖過……

【編程題】

1、手串。

/** 請完成下面這個函數,實現題目要求的功能 **/
/** 當然,你也可以不按照這個模板來作答,完全按照自己的想法來 ^-^  **/

#include <stdio.h>  
#include <math.h>  
#include <stdlib.h>  
#include <iostream>
using namespace std;

int strand[10010][51];
int color_list[51];

int main()
{
    int n,m,c;
    scanf("%d", &n);
    scanf("%d", &m);
    scanf("%d", &c);
    //init
    for (int i=0;i<n;i++)
    {
        int len=0,color=0;
        cin>>len;
        for (int j=0;j<len;j++)
        {
            cin>>color;
            strand[i][color]=1;
        }
    }
    int ret=0;

    //do process

    for(int i=0;i<n;i++)
    {
        for(int j=1;j<51;j++)
        {
            if (strand[i][j] == 1 && color_list[j]==0)
            {
                for(int k=1;k<m;k++)
                {
                    int column = ( i+k )%n;
                    if(strand[column][j]==1)
                    {
                        ret++;
                        color_list[j]=1;
                        break;
                    }
                }
            }
        }
    }
    cout<<ret<<endl;

}

2、興趣計數。

#include <vector>
#include <iostream>

using namespace std;

int users[300010];
int query[300010][3];

int query_num(int l,int r,int k)
{
    int ret=0;
    for(int i=l;i<=r;i++)
    {
        if(users[i]==k)
            ret++;
    }
    return ret;
}

int main()
{
    //init
    int n,q;
    cin >> n;
    for (int i=1;i<=n;i++)
        cin>>users[i];
    cin>>q;
    for (int i=0;i<q;i++)
    {
        cin>>query[i][0];
        cin>>query[i][1];
        cin>>query[i][2];
    }
    //process
    for(int i=0;i<q;i++)
    {
        cout<<query_num(query[i][0],query[i][1],query[i][2])<<endl;
    }

}

附加1【編程題】

輸出3騙了15%……

附加2【設計題】

今日頭條會根據用戶的瀏覽行爲、內容偏好等信息,爲每個用戶抽象出一個標籤化的用戶畫像,用於內容推薦。用戶畫像的存儲、高併發訪問,是推薦系統的重要環節之一。現在請你給出一個用戶畫像存儲、訪問方案,設計的時候請考慮一下幾個方面:

  • 用戶畫像如何存儲
  • 如何保證在線高併發、低延遲的訪問
  • 機器宕機、負載均衡問題
  • 如果用戶增長很快,在你的方案下,該如何擴容

1、建立用戶關係映射表,用戶和標籤爲常量,關係爲映射。保存用戶畫像最好使用緩存,比如memcached,同時後端要落地到DB。
2、有了內存緩存的話,訪問速度自然會有提升,除此之外,還要提高緩存的利用率,這樣請求不會到DB去請求。3、同時還要減少單機查詢流量,將不同用戶分配到不同的機器上,可以採用分佈式,比如按照用戶的地區、ID的號段進行分開,這樣每個機器的請求都是獨立的,可以命中緩存,提高系統的性能。
4、一致性哈希,保證節點變化後用戶訪問的機器不變,比如之前在1號機器訪問的用戶還是到1號機器。

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