演算法面試題之字串子串
“字串子串”是網易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);
}
}
排序的時候,我選擇了快速排序,因此排序的時間複雜度為
相關推薦
演算法面試題之字串子串
“字串子串”是網易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 所屬網站分類: 面試經典
java面試題:如果一串字符如"aaaabbc中國1512"要分別統計英文字符的數量,中文字符的數量,和數字字符的數量,假設字符中沒有中文字符、英文字符、數字字符之外的其他特殊字符。
rgs info log letter clas [] 面試題 .com ack package com.swift; public class TotalNumber_String { public static void main(String[] arg
面試題之演算法面試題(一)
問題: 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