1. 程式人生 > >演算法面試題之字串子串

演算法面試題之字串子串

“字串子串”是網易2017年校園招聘題。

題目:

一種雙核CPU的兩個核能夠同時的處理任務,現在有n個已知資料量的任務需要交給CPU處理,假設已知CPU的每個核1秒可以處理1kb,每個核同時只能處理一項任務。n個任務可以按照任意順序放入CPU進行處理,現在需要設計一個方案讓CPU處理完這批任務所需的時間最少,求這個最小的時間。

輸入描述:

輸入包括兩行:
第一行為整數n(1 ≤ n ≤ 50)
第二行為n個整數length[i](1024 ≤ length[i] ≤ 4194304),表示每個任務的長度為length[i]kb,每個數均為1024的倍數。

輸出描述:

輸出一個整數,表示最少需要處理的時間

輸入例子1:

5

3072 3072 7168 3072 1024

輸出例子1:

9216

解決思路

首先,我們先認真審題,看看需要注意的地方:

1.CPU是雙核的,每個核同時只能處理一項任務,並且1秒可以處理1kb;

2.有n個已知的資料量要交給CPU處理,n個任務可以按照任意順序放入CPU中處理;

3.目的:設計一個方案,讓CPU處理完這n個任務所需的時間最少,並求這個最小的時間。

4.輸入值:整數n(1 ≤ n ≤ 50),n個整數length[i](1024 ≤ length[i] ≤ 4194304),每個數均為1024的倍數。

5.輸出值:最少需要處理的時間

理解完題目的意思後,我們發現,要使得CPU處理完這n個任務所需的時間最少,那麼,我們就應該充分地利用這2個核,即,同一時間,儘可能地讓兩個核都在工作,這樣就可以最小化處理時間。

那麼,如何儘可能保證兩個核在同一時間都在工作呢?

我想到一種方案,就是長度大的任務必須優先處理。即,我們可以先對任務長度進行排序,兩個核再依次從大到小處理任務。

public class Substring {

    public int substring(int n, int[] length){

        //輸入值合法性驗證
        if(n < 1 || n > 50)
            throw new IllegalArgumentException("輸入值n不合法");
        if(length.length != n)
            throw
new IllegalArgumentException("輸入值length不合法"); for(int i = 0;i < n;i++){ if(length[i] < 1024 || length[i] > 4194304 || length[i] % 1024 != 0) throw new IllegalArgumentException("輸入值length不合法"); } //利用快排對length排序 quickSort(length, 0, n-1); int time = 0; int core1 = n-1;//第一個核先處理最大長度的任務 int core2 = n-2; int temp1 = length[core1]; int temp2 = 0; while(core1 > 0 && core2 > 0){ temp2 = 0; for(int j = core1-1;j >= 0;--j){ core2 = j;//第二個核處理length[j] if((temp2+length[core2]) > temp1){ temp2 += length[core2] - temp1;//core1處理完任務後,core2還剩多少長度任務沒處理 time += length[core2]-temp2;//累加已經處理的部分 break; }else{ temp2 += length[core2]; time += length[core2]; } } if(core2 == 0) //如果此時core2已經處理完最後一個任務,則結束 break; temp1 = 0; for (int i = core2-1;i >= 0;--i){ core1 = i; if((temp1+length[core1]) > temp2){ temp1 += length[core1] - temp2;//core2處理完任務後,core1還剩多少長度任務沒處理 time += length[core1]-temp1;//累加已經處理的部分; break; }else{ temp1 += length[core1]; time += length[core1]; } } } //累加最後一個任務沒有處理完的部分 if(core1 == 0) time += (temp2-temp1); else if(core2 == 0) time += (temp1-temp2); return time; } /* *快速排序 * // 時間複雜度:T(n)=O(nlogn) // 空間複雜度:S(n) = O(logn) // 穩定性:不穩定排序 */ void quickSort(int arr[], int start, int end) { if(start < end){//判斷start是否等於end,如果等於則說明各區間只有一個數 int i = start; int j = end; int x = arr[start];//將start作為基準數 while(i < j){//如果i=j,則結束 while(i < j && arr[j] >= x) // 從右向左找第一個小於x的數 j--; //此時,arr[j] < x,則令arr[i]=arr[j],且i向前移動一格 if(i < j) arr[i++] = arr[j]; while(i < j && arr[i] < x)// 從左向右找第一個大於等於x的數 i++; //此時,arr[i] >= x,則令arr[j]=arr[i],且j向後移動一格 if(i < j) arr[j--] = arr[i]; } //此時,arr[i]=arr[j]=x,且比x大的數全在它的右邊,小於或等於它的數全在其左邊。下面則再對其左右區間重複這個步驟 arr[i] = x; quickSort(arr,start,i-1);//對其左邊區間重複上述操作 quickSort(arr,i+1,end);//對其右邊區間重複上述操作 } } public static void main(String[] args) { Substring substring = new Substring(); int n = 5; int[] length = {3072,3072,7168,3072,1024}; int time = substring.substring(n,length); System.out.print(time); } }

排序的時候,我選擇了快速排序,因此排序的時間複雜度為O(nlogn),後面遍歷length陣列所花費的時間複雜度為O(n),因此,本方案的時間複雜度為O(nlogn)

相關推薦

演算法試題串子

“字串子串”是網易2017年校園招聘題。 題目: 一種雙核CPU的兩個核能夠同時的處理任務,現在有n個已知資料量的任務需要交給CPU處理,假設已知CPU的每個核1秒可以處理1kb,每個核同時只能處理一項任務。n個任務可以按照任意順序放入CPU進行處理,現在需

Java(試題):截取

int lan out 試題 void trace 題目 replace odi 在Java中,字符串“abcd”與字符串“ab你好”的長度是一樣,都是四個字符。 但對應的字節數不同,一個漢字占兩個字節。 定義一個方法,按照指定的字節數來取子串。 如:對於“ab你好”,如果

試題的全排列

width pan string || per 回溯法 圖片標題 [] 描述 題目描述:輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。 思路:回溯

前端常見演算法試題 - 從尾到頭列印連結串列[JavaScript解法]

前端常見演算法面試題之 - 從尾到頭列印連結串列[JavaScript解法] 題目描述 實現思路 程式碼實現 題目描述 輸入一個連結串列的頭結點,從尾到頭反過來打印出每個結點的值 實現思路 前端工程師看到這個題目,直接想到的就是

前端常見演算法試題 - 二維陣列中的查詢[JavaScript解法]

前端常見演算法面試題之 - 二維陣列中的查詢[JavaScript解法] 題目描述 輸入輸出分析 實現思路 程式碼實現 題目描述 在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個

演算法試題對n個數排序

這個題用上一篇部落格中演算法面試題之統計詞頻前k大中的基於檔案的歸併排序演算法顯然是可以秒殺的,但是不是很好寫,這道題目強調了每個數字都小於10^7,而且不會出現重複的數字,又給了1M的記憶體,因此必然是想讓我們用一個其他的演算法去搞定他,怎麼搞定呢?我們來看題目裡面出現的不和諧的描述!不會出現重複的數字,

試題中查找出第一個只出現一次的符的位置

c++ bit int 相同 出現一次 試題 ems 出現次數 更新 樣例:比如“abcdabc”,第一個只出現一次的字符為d,位置為3 解決方案1:O(n*n)的復雜度 遍歷字符串中的每個字符,然後用該字符在字符串中進行查找,如果沒有找到

試題O(n)內旋轉

col 旋轉字符串 方案 面試 長度 字符 特點 發現 慣性 樣例: 字符串“abcd1234"左移3位結果為”234abcd1“ K:左移位數 L:字符串長度 方案1:暴力 O(K * L) 可以每次將數組中的元

python試題如何計算一個的長度

tty src python面試題 log 鏈接 字符串 ont cat 分享 在我們想計算長度的字符串上調用函數len()即可 >>> len(‘hhhhhhhhjg‘) 10 所屬網站分類: 面試經典

試題演算法試題(一)

問題: 1. 輸入一個個數較大的正整數陣列[數字範圍在0~9999],將部分陣列元素的十進位制表示連線起來排成一個數,輸出能排出的所有數字中最大的一個。find例如輸入陣列{3423,33,456,9,8,7,21}和3,則輸出的最大數為:456342333。 要求: (1) 輸出數字用

【ForOffer】【深信服--測試開發崗筆試題】求最少車費&求最低位&找馬甲&找串子

深信服的整體筆試題難度一般,有多刷題的經驗,能立馬找出了題意理解,在此,自己只是做個總結髮出,有更好的解法的童靴可以一起交流,其實這四道題都是常見題型的一種變形。程式碼照著搬都是沒有問題的哦! 第一題:求最低位  關鍵點說明:主要是對二進位制轉換,並且擷取到了從右

C++試題資料結構和演算法

  C++面試題之資料結構和演算法 目錄 1、String原理及實現 2、連結串列的實現 2.1、順序連結串列 2.2、鏈式表 2.3、雙鏈表 2.4、迴圈連結串列 3、佇列 3.1、順序佇列 3.2、鏈式佇列 4、棧 4.1、順序棧

試題演算法部分】二叉樹的遍歷

本篇文章主要目的是詳細討論二叉樹的前序、中序和後序遍歷演算法,包括遞迴版和迭代版。首先給出遞迴版的一般思想: 前序遍歷:先訪問根節點,前序遍歷左子樹,前序遍歷右子樹。 中序遍歷:中序遍歷左子樹,訪問根節點,中序遍歷右子樹。 後序遍歷:後序遍歷左子樹,後序遍歷

演算法】求串子的高效實現

出處 有一道秋招筆試題是這樣: 輸入兩個正整數n、d(1<=d<=1000),把n看成字串,求n的所有子串中能被d整除的子串的個數。 示例1: 輸入:1234 4,輸出:4,說明:12、124、24、4 示例2: 輸入:616 3,輸出:3,說明:6、

PHP 演算法試題(一)

氣泡排序演算法 基本思想: 對需要排序的陣列從後往前(逆序)進行多遍的掃描,當發現相鄰的兩個數值的次序與排序要求的規則不一致時,就將這兩個數值進行交換。這樣比較小(大)的數值就將逐漸從後面向前面移動。 <?php function m

基礎試題資料結構與演算法

資料結構 資料結構是對實際問題中的資料元素及相互間的聯絡的抽象。一般用線性表來表示常用資料結構,線性表分為順序儲存的順序表和連式儲存的連結串列。 常用資料結構 在學習演算法之前,必須要了解一些常用資料結構的概念。 棧:一種特殊串聯形式的抽象資料型別,可由連結串列或陣列實現,通過連結串列或陣列的

Top-K問題(java試題演算法類)

Top-K問題,不難,思路優化過程: 1.全域性排序  O(n*lg(n)) 2.區域性排序,只排序topK個數,氣泡排序前k個,O(n*k) 3.堆排序,topK個數也不用排序了,O(n*lg(k))

C++試題寫一個在一個字串中尋找一個子第一個位置的函式

#include <iostream> using namespace std; int search_str(char *strDest ,const char *strSrc, int n ) { int count = 1;

一文搞懂高頻試題限流演算法,從演算法原理到實現,再到對比分析

限流是指在系統面臨高併發、大流量請求的情況下,限制新的流量對系統的訪問,從而保證系統服務的安全性。常用的限流演算法有計數器固定視窗演算法、滑動視窗演算法、漏斗演算法和令牌桶演算法,下面將對這幾種演算法進行分別介紹,並給出具體的實現。本文目錄如下,略長,讀者可以全文閱讀,同樣也可以只看感興趣的部分。 [TOC