面了一次百度,暫時完成兩輪技術面試,感覺每次都好多題目,並且有一些不知道怎麼回答,看來准備的還是不夠好。
先分享一個題目吧:
給出一個長度是N的數組,現在要找出最大的兩個元素,最少要多少次比較。
分析: 如果找出1個最大的,比較次數無疑是 n - 1,
現在如果已經找出最大的了,那麼再找第二大的,如果用競賽排序的方法,可以再使用 logn就可以找到了。 不過不知道怎麼證明 這是最小次數。
順便實現了一下 競賽排序。
- public class TournamentSort {
-
-
- private class Node//用node來存儲競賽排序過程中的節點,包括裡面的數據和數據在數組中的ID
- {
- public int data;
- public int id;
-
- public Node()
- {
-
- }
- public Node(int _data, int _id)//
- {
- data = _data;
- id = _id;
- }
- }
- public void Adjust(Node[] data, int idx)//當去除最小元素以後,我們要調整數組
- {
- while(idx != 0)
- {
- if(idx % 2 == 1)//當前id是奇數,說明並列的是idx + 1, 父節點是 (idx-1)/2
- {
- if(data[idx].data < data[idx + 1].data)
- {
- data[(idx - 1)/2] = data[idx];
- }
- else
- {
- data[(idx-1)/2] = data[idx + 1];
- }
- idx = (idx - 1)/2;
- }
- else
- {
- if(data[idx-1].data < data[idx].data)
- {
- data[idx/2 - 1] = data[idx-1];
- }
- else
- {
- data[idx/2 - 1] = data[idx];
- }
- idx = (idx/2 - 1);
- }
- }
- }
-
-
- public void Sort(int[] data)
- {
- int nNodes = 1;
- int nTreeSize;
- while(nNodes < data.length)
- {
- nNodes *= 2;
- }
- nTreeSize = 2 * nNodes - 1;//競賽樹節點的個數, nNode算出來是為了做成滿二叉樹
-
- Node[] nodes = new Node[nTreeSize];//競賽樹用數組存儲
- //initialize the data
-
- int i, j;
- int idx;
- for( i = nNodes - 1; i < nTreeSize; i++) //初始化競賽樹數據
- {
- idx = i - (nNodes - 1);
- if(idx < data.length)
- {
- nodes[i] = new Node(data[idx], i);
- }
- else
- {
- nodes[i] = new Node(Integer.MAX_VALUE, -1);//對於補充的數據,我們初始化成最大。
- }
-
- }
-
- for( i = nNodes - 2; i >= 0; i--)//
- {
- nodes[i] = new Node();
- if(nodes[i * 2 + 1].data < nodes[i * 2 + 2].data)
- {
- nodes[i] = nodes[i*2 + 1];
- }
- else
- {
- nodes[i] = nodes[i*2 + 2];
- }
- }
- //the real sorting procedure
- for( i = 0; i < data.length; i++)//實際排序的過程
- {
- data[i] = nodes[0].data;//取出最小的
- nodes[nodes[0].id].data = Integer.MAX_VALUE;
- Adjust(nodes, nodes[0].id);
-
- }
-
-
-
- }
- }