程式設計題:(一)數字規律
(一)陣列中出現次數超過一半的數字(如果不存在則輸出0)
假設不會出現0超過一半的情況;若有可以設定一個全域性的bool變數來檢查。
(1)解法一:利用map;鍵值為陣列中元素值,關聯值為數出現的次數
int MoreThanHalfNum_Solution(vector<int> numbers) { int len=numbers.size(); map<int,int> ma; if(len==0) return 0; for(int i=0;i<len;i++) ++ma[numbers[i]]; for(map<int,int>::iterator mapIte=ma.begin();mapIte!=ma.end();mapIte++) { if(mapIte->second>len/2) return mapIte->first; } return 0; }
(2)解法二:
思路:因為陣列中有一個數字出現的次數超過陣列長度的一半,也就是說出現的次數比其它所有數字出現的次數的和還要多。因此可以儲存兩個值:一個數組中的數字,一個是次數。遍歷陣列,如果陣列中的下一個數字與之前儲存的數字相同則次數加1;如果不同則次數減1;如果次數為0,則儲存下一個數字並把次數設為1.最後一次把次數設為1的數字即為對應的數字。
int MoreThanHalfNum_Solution(vector<int> numbers) { int len=numbers.size(); if(len==0) return 0; //兩兩比較最後一個使times變為1的即為要找的數 int times=1; int result=numbers[0]; for(int i=1;i<len;i++) { if(times==0)//如果次數為0,則將次數設為1,並儲存當前的數字 { times=1; result=numbers[i]; } else { if(numbers[i]==numbers[i-1]) { times++; result=numbers[i]; } else { times--; } } } //檢查result是否超過一半 times=0; for(int i=0;i<len;i++) { if(numbers[i]==result) times++; } if(times<=len/2) result=0; return result; }
(二)陣列中最小的K個數
方法一:利用 大頂堆,堆初始化為陣列前k個元素。然後將陣列中剩下的元素與堆中最大值進行比較,若比堆中最大值小則進行替換。自己實現堆太複雜,可以利用STL中的set來模擬;set底層利用紅黑樹來實現,set會自動排序,因此可以以O(1)時間找出最大值;紅黑樹的插入和刪除操作都只需要O(logk)時間。
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int> vec; int len=input.size(); if(len<k||k<=0) return vec; multiset<int> intSet(input.begin(),input.begin()+k);//初始化intSet中為vector中前k個數 for(int i=k-1;i<len;i++) { if(input[i]<*(intSet.rbegin()))//判斷是否小於intSet中的最大值,若小於則進行替換 { intSet.erase(*(intSet.rbegin()));//set的迭代器是const的不能直接賦值,set不支援遞減操作 intSet.insert(input[i]);//因此只能使用反向迭代器來獲取最後一個值。或者定義時指定set為降序,獲取第一個值 } } for(multiset<int>::iterator iteSet=intSet.begin();iteSet!=intSet.end();iteSet++) { vec.push_back((*iteSet)); } return vec; }
方法二:可以借鑑快排的思想。快排每次排序會使第n個元素,排在第n位;因此利用快排的思想,當第k個元素在第k位時,前k個元素即為最小的k個。(缺點是:不適合於大資料處理)
(三)連續子陣列的最大和
思路:如果第k個數之前累加的和是負數,則加上第k個數後的值肯定小於等於第k個數,因此:若之前累加的和是負數則用當前值覆蓋之前值。如果之前的累加值大於0,則繼續累加。若加上第k個數後累加值大於之前的,則更新累加的最大值。
int FindGreatestSumOfSubArray(vector<int> array)
{
int greatSum=0x80000000;
int len=array.size();
if(len==0)
return 0;
int currentSum=0;
for(int i=0;i<len;i++)
{
if(currentSum<0)
currentSum=array[i];
else
currentSum+=array[i];
if(currentSum>greatSum)
greatSum=currentSum;
}
return greatSum;
}
(四)一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次。找出這兩個只出現一次的數字。
思路:兩個相同的數異或為0;0與任何數異或仍然是該數。總體思路將這兩個只出現一次的數分為兩組,然後分別對每一組進行異或。因為兩個不同的數的二進位制至少有一位不同即:異或後至少有一位為1;根據異或後第一個為1的位將原陣列分成兩個陣列,即可以將兩個值出現一次的數分到兩個數組裡。再分別對兩個陣列異或即可。
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2)
{
int len=data.size();
if(len<2)
return;
int tempNum=0;
for(int i=0;i<len;i++)
tempNum^=data[i];//找出兩個數中不同的位
int flag=1;
while(!(flag&tempNum))//找出第一個不同的位
flag=flag<<1;
*num1=0;
*num2=0;
for(int i=0;i<len;i++)//根據不同的位將陣列分成兩組,分別異或,得到結果
{
if((flag&data[i])==0)//==的優先順序高於&
*num1^=data[i];
else
*num2^=data[i];
}
}
(五)一個整型陣列有一個數只出現1次,其它數都出現3次,求這個數
思路:對各個數進行二進位制位加和;若某位上二進位制上1的個數為3的倍數,則該數的在該位上的二進位制位0;若某位上的1的個數不是3的倍數,則該數在該位上的二進位制位1。
(六)1001個數字,1~1000中有一個出現兩次,其餘都出現一次
(1^2^3…..^1000)^(a[0]^a[1]^…..a[1000])
(七)尋找陣列中最大值和最小值
方法一:N中的每個數分別和max,min比較,大於max的就不必和min比較,小於min的也不必和max比較。因此比較的次數不足2N次
方法二:陣列中的一對一對的數相互比較,比較中較大的一個和max比較,較小的和min比較,總計有N/2對數,分別和max和min進行一次比較,共計3N/2次比較
方法三:兩個數為1組,將大的放在偶數位,小的放在基數位。然後在偶數位找大的,基數為找小的。
方法四:分治策略:分別求出前後N/2個數的min和max,然後,取較小的min,較大的max即可。
(八)找出N個數中的第二大數
思路:用兩個變數分別存最大值max和次大值secondMax,遍歷陣列:如果arr[i] > max,則更新secondMax=max,max=arr[i];否則如果arr[i] > secondMax,則更新secondMax=arr[i];否則,不進行更新操作。
這個方法最多的比較次數為2*N次,最小N次。
int secondMaxNum(int num[],int length)
{
assert(num!=NULL&&length>=2);
int max=num[0];//不能為0,因為陣列中可能全為負數
int secondMax=num[1];//不能為num[0],否則若陣列第一個為最大時,則secondMax無法更新
for(int i=0;i<length;i++)
{
if(num[i]>max)
{
secondMax=max;
max=num[i];
}
else if(num[i]>secondMax&&num[i]<max)
secondMax=num[i];
}
return secondMax;
}
(九)找出連結串列中第二大和第二小的數
思路:定義是個變數:最大,次大,最小,次小。每個數可能有五個區間(畫個橫座標好分析);對五個區間進行判斷,一遍掃描既可判斷
(十)100個整數中取出一個,怎麼判斷取出的是哪個(CVTE)
方法一:把取之前所有的數加和再減去取之後的數即可得到。(可能會越界)
方法二:把取之前的與取之後的合成一個數組,然後排序。再遍歷一遍即可找到。(對於取出2個的情況也適用)
方法三:先把100個數排序,再把99個排序,然後一一對比。(對於取走多個數的情況也適用)
方法四:對100個數建一個hash表,再一個個找,沒有找見的即為刪除的。
(十一)兩個32位整數m,n的二進位制中有多少位不同
方法一:兩個數異或得到的數的二進位制中1的個數即為不同的位的個數。二進位制中1的個數:一個數與自己減1相與,統計的即是這個數最右邊為1的位。
int getDifference(int const m,int const n)
{
int differenceNum=m^n;
int count=0;
while(differenceNum)
{
differenceNum=differenceNum&(differenceNum-1);
++count;
}
return count;
}
方法二:分別兩個數的二進位制表示的每一位使1還是0;然後對每一位進行異或。
int getDifference(int const m,int const n)
{
int count=0;
int flag=1;
while(flag)
{
if((flag&m)^(flag&n))//分別求出每一位為1還是0,再進行異或
++count;
flag<<=1;
}
return count;
}
(十二)n!末尾的0的個數
思路:因為只有一個偶數乘以5的倍數才會產生10,因為偶數的個數比5的因子個數多,因此統計小於n的數中5的因子的個數即可。注意25提供兩個5......
方法一:統計每個數中可以提供的5的因子個數
int last0Num(int n)
{
int count=0;
for (int i=1;i<=n;i++)
{
int j=i;
while(j%5==0)
{
count++;
j=j/5;
}
}
return count;
}
方法二:統計不大於n的數中5的倍數,25的倍數,125倍數....分別有多少
int last0Num(int n)
{
int count=0;
while(n)
{
count+=n/5;
n=n/5;
}
return count;
}
相關推薦
程式設計題:(一)數字規律
(一)陣列中出現次數超過一半的數字(如果不存在則輸出0) 假設不會出現0超過一半的情況;若有可以設定一個全域性的bool變數來檢查。 (1)解法一:利用map;鍵值為陣列中元素值,關聯值為數出現的次數 int MoreThanHalfNum_Solution(
併發程式設計學習:java併發程式設計的藝術(一)
一: 1.併發與並行:併發是多個執行緒(任務)共同爭奪一個cpu進行處理,並行是多個cpu各自處理對應的執行緒任務,現階段都只是併發而不是真正意義上的並行。 2.上下文切換: 即使單行處理器也支援多執行緒執行任務,cpu通過給每個執行緒分配cpu時
LeetCode 刷題指南(一):為什麼要刷題
雖然刷題一直飽受詬病,不過不可否認刷題確實能鍛鍊我們的程式設計能力,相信每個認真刷題的人都會有體會。現在提供線上程式設計評測的平臺有很多,比較有名的有 hihocoder,LintCode,以及這裡我們關注的 LeetCode。 程式碼提交曲線 LeetCode
【如何自學程式設計系列】(一):如何做到無師自通?
無數莘莘學子為了理想,進行著他鄉求知的旅途。求學生活你要怎麼渡過呢?你是要先享受來之不易的求學生活呢還是繼續為人生目標而奮鬥。閒言少敘,當今社會一步拉下很有可能步步落後。得有憂患意識。誰也不想上完大學結果被大學給上了,畢業季很有可能就是失業季。 每個人都有自己的理想和人生目標,程式設計也
【怎樣寫程式碼】函數語言程式設計 -- Lambda表示式(一):引出
如果喜歡這裡的內容,你能夠給我最大的幫助就是轉發,告訴你的朋友,鼓勵他們一起來學習。 If you like the content here, you can give me the greatest help is forwarding, tell you
雲平臺程式設計與開發(一):Java雲平臺服務商一覽
因為Java語言的跨平臺性和高度靈活性,成為目前雲端計算平臺的主流開發語言;所以,這裡重點討論一下Java 雲平臺的比較情況。尤其是討論X5Cloud雲平臺與現有幾個Java雲平臺的聯絡和區別: * App Engine (http://code.google.com/appengine/)
程式設計與數學(一):計算玩家面對面
最近聽到這樣一個需求,VR多人遊戲的時候,當兩個玩家面對面的情況下,才可以開始下一個流程: 聽到一個人的解決方案是算距離,具體沒問,覺得略感複雜,趁此機會也發揮程式與數學的相關性一直很強,從此篇開始會專門寫一些程式與數學應用的部落格。 好了切入正題,每個角色
Re:從0開始的微服務架構:(一)重識微服務架構--轉
相關 推廣 模塊劃分 ati 滿足 face jar 點擊放大 積累 原文地址:http://www.infoq.com/cn/articles/micro-service-architecture-from-zero?utm_source=infoq&utm_me
linux經典 題庫(一)
awk grep sed1.1創建一個目錄/data。1) 解答: mkdir /data擴展:mkdir後面可以加參數-p,表示遞歸創建,也可以加參數-v,表示可以顯示出創建的過程。1.2為oldboy.txt增加內容為“I am studying linux.”。解答:為文
前端開發規範手冊:(一)基本原則
name ges rop scrip 有效 object sel 代碼 charset 1、結構、樣式、行為分離 盡量確保文檔和模版只包含HTML結構,樣式都放到樣式表中,行為都放到腳本裏。 2、縮進 統一兩個空格縮進(總之縮進統一即可),不要使用Tab鍵或者Tab
JVM學習筆記(一)數字在JVM中的表示
oat 技術 3-9 cnblogs es2017 ext ava bsp eee 數字在JVM中的表示 一、整數在JVM中的表示 1.在Java虛擬機中,整數有四種表示: byte:8位 short:16位 int:32位 long:64位
【微服務從入門到精通】:(一)微服務的藍綠發布及灰度發布
采樣 前端 入門 後端 blog 文件 風險 性能 切換 藍綠部署 基本上,藍綠部署是一種以可預測的方式發布應用的技術,目的是減少發布過程中服務停止的時間。 簡單來說,你需要準備兩個相同的環境(基礎架構),在藍色環境運行當前生產環境中的應用,也就是舊版本應用,如圖中 A
從0開始的微服務架構:(一)重識微服務架構
拆分 dock try 快速入門 比較 資源 貼吧 升級維護 頁面 導語 雖然已經紅了很久,但是“微服務架構”正變得越來越重要,也將繼續火下去。 各個公司與技術人員都在分享微服務架構的相關知識與實踐經驗,但我們發現,目前網上的這些相關文章中,要麽上來就是很有借鑒意義的幹貨,
python3學習筆記(一)——數字、字符串、列表、字典、元組
類型 單詞 nbsp 3.1 true expand 替換 割點 gpo 什麽是python解釋器?
深入理解JVM虛擬機:(一)Java運行時數據區域
字面量 符號 地方 64位 因此 lower 優化 java堆大小 工作 概述 JVM是Java語言的精髓所在,因為它Java語言實現了跨平臺運行,以及自動內存管理機制等,本文將從概念上介紹JVM內存的各個區域,說明個區域的作用。 JVM運行時數據區模型 Java虛擬機在執
eureka服務註冊與發現:(一)搭建註冊中心
hostname dubbo efault 必須 技術分享 不存在 dea bsp 啟用 最近由於工作中需要將原來的spring項目都進行架構調整,要實現應用解耦,所以考慮到通過微服務的方式將應用解耦。所以面臨兩個選擇:dubbo 和spring cloud ,由於項目規模
日常代碼優化系列:(一)獲取url參數
分別是 對象 https 結果 font 被調用 undefined span repl 最近刷牛客網的時候,看到某大神寫的 獲取url參數 的簡潔寫法,正則用的那叫一個6,頓時心生敬佩,趕緊來學習膜拜一下~~ 題目描述:獲取 url 中的參數 1. 指定參數名稱,返回該
Android 開發:(一)安卓開發環境搭建與配置 (Windows和Mac )以及目錄結構介紹
(一)、windows版 一. 開發工具: 1.Android Studio:(http://www.androiddevtools.cn/) 2.Genymotion(虛擬機器):(http://www.genymotion.net/) (二)、Mac版 一
PL/SQL程式設計基礎知識(一)
--PL/SQL變數的宣告和賦值 declare v_ename varchar2(30);--定義變數 begin v_ename:='&請輸入名字';--接受鍵盤輸入 dbms_output.put_line(v_ename); end; --put_line :列印換行
zuul:(一)SpringCloud的閘道器介紹和zuul閘道器的使用
1)什麼是閘道器? API Gateway,是系統的唯一對外的入口,介於客戶端和伺服器端之間的中間層,處理非業務功能 提供路由請求、鑑權、監控、快取、限流等功能 統一接入 智慧路由