數據結構和算法是面試的一座大山,尤爲去面試大廠更是必不可少!簡單說明一下爲啥喜歡考數據結構和算法,首先,算法有用也沒用,若是是中小型企業的簡單業務邏輯,可能用不到啥算法,但大廠必定會用到,都知道數據庫底層會用到紅黑樹、B++樹等,去oracle公司,那數據結構必定要玩轉,再加入想去阿里,百萬數據量,不會算法去優化,可能阿里早倒閉,但小長數據量會比較少,用算法就沒什麼必要了。ios
給定一個數組,求若是排序以後,相鄰兩數的最大差值,要求時間複雜度O(N),且要求不能用基於比較的排序。面試
桶排序應該都知道吧,跟計數排序和基數排序都是非比較排序,像快排、歸併都是比較排序。其實,桶排序是一種思想,具體實現是計數排序和基數排序。算法
接下來直接來分析題目,以下: 數據庫
若是有N個數,準備N+1個桶,數組
遍歷找到最小值和最大值數據結構
假如,有9個數,準備10個桶,中間一定存在最少一個空桶,說明最大差值必定不在一個桶內,但不必定在空桶兩邊。oracle
舉例子以下:less
三個數,四個桶,最大差值19數據結構和算法
19 空桶 30 49 ide
以下:
#include<iostream> #include<vector> #include<climits> using namespace std; class Solution{ public: int maxGap(vector<int> &nums){ if(nums.size() < 2) return 0; int len = nums.size(); int min_index = INT_MAX; int max_index = INT_MIN; //找出數組的最大值和最小值 for(int i=0;i<nums.size();i++){ min_index = min(min_index,nums[i]); max_index = max(max_index,nums[i]); } if(min_index == max_index) return 0; bool *hasNum = new bool[len+1]; //每一個桶是否被訪問過 int *maxs = new int[len+1]; //最大值數組 int *mins = new int[len+1]; //最小值數組 int bid = 0; for(int i = 0;i<len;i++){ bid = bucket(nums[i],len,min_index,max_index); //造成桶 mins[bid] = hasNum[bid] ? min(mins[bid],nums[i]) : nums[i]; //給最大值桶賦值 maxs[bid] = hasNum[bid] ? max(maxs[bid],nums[i]) : nums[i] ; //給最小值桶賦值 hasNum[bid] = true; } int res = 0; int lastMax = maxs[0]; for(int i=1;i<len;i++){ if(hasNum[i]){ res = max(res,mins[i]-lastMax); lastMax = maxs[i]; } } return res; } private: int bucket(int num,int len,int min1,int max1){ return (int) ((num-min1)*len/(max1-min1)); } }; int main() { int temp[] = {11,2,44,50,67}; vector<int> nums(temp,temp+5); cout << "max:" << Solution().maxGap(nums) << endl; return 0; }
用數據實現固定大小的隊列和棧
隊列和和棧的特性分別是:先進先出和先進後出,思路分析見下圖:
圖上,標註的很明白了,有不明白的歡迎留言
首先是數組實現棧,代碼以下:
#include<iostream> #include<vector> using namespace std; class ArrayStack{ private: int index; //插入位置的下標 int *arr; int maxSize; public: ArrayStack(int initSize){ if(initSize < 0) throw "The initSize is less than 0"; arr = new int[initSize]; index = 0; maxSize = initSize; } void push(int num){ //壓入棧 if(index == maxSize) throw "The stack is full"; arr[index++] = num; } int pop(){ if(index == 0) throw "The stack is empty"; return arr[--index]; } }; int main() { ArrayStack stack1 = ArrayStack(3); stack1.push(2); stack1.push(3); stack1.push(1); cout << "num:" << stack1.pop() << endl; return 0; }
用數組實現隊列,代碼以下:
#include<iostream> #include<vector> using namespace std; class ArrayQueue{ private: int *arr; int size; int start; //彈出下標 int end; //插入下標 int maxSize; //數組最大值 public: ArrayQueue(int initSize) { if(initSize < 0) throw "The initSize is less than 0"; arr = new int[initSize]; size = 0; start = 0; end = 0; maxSize = initSize; } void push(int num){ if(size == maxSize) throw "the queue is full"; size++; arr[end] = num; end = end==maxSize-1?0:end+1; //讓end能夠在數組中循環跑 } int pop(){ if(0 == size) throw "the queue is empty"; size--; int tmp = start; start = start==maxSize-1?0:start+1; //跟end同樣在數組中循環跑 return arr[tmp]; } }; int main() { ArrayQueue arrQueue = ArrayQueue(3); arrQueue.push(1); arrQueue.push(2); cout << "num:" << arrQueue.pop() << endl; return 0; }
實現一個特殊的棧,在實現棧的基本功能上,再實現返回棧中最小元素的操做。
【要求】
直接上圖,以下:
代碼以下:
#include<iostream> #include<vector> #include<stack> using namespace std; class GetMinStack{ private: stack<int> stackData; stack<int> stackMin; public: void push(int num){ if(stackMin.empty()){ stackMin.push(num); }else if(num <= getmin()){ stackMin.push(num); } stackData.push(num); } int pop(){ if(stackData.empty()) throw "the empty"; int value = stackData.top(); stackData.pop(); if(value == getmin()){ stackMin.pop(); } return value; } int getMin(){ //獲取最小值 if(stackMin.empty()) throw "the stackMin is empty"; return stackMin.top(); } int getmin(){ if(stackMin.empty()) throw "the stack is empty"; return stackMin.top(); } }; int main() { GetMinStack minStack = GetMinStack(); minStack.push(1); minStack.push(3); minStack.push(2); cout << "pop num:" << minStack.pop() << endl; cout << "min num:" << minStack.getMin() << endl; return 0; }
會繼續分享面經和算法,但願持續關注!