面試題:最小的k個數
題目:輸入n個整數,找出其中最小的k個數,例如,輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4
【方法一】
將整數排序,排序後位於最前面的k個數則為最小的k個數。時間複雜度為o(nlogn)
【方法二——需要修改陣列】
可以基於快排的部分演算法來解決問題(partition)。
可基於陣列的第k個數字來調整,使得比第k個數字小的所有數字都位於陣列的左邊,比第k個數字大的所有數字都位於陣列的右邊。這樣調整之後,位於陣列左邊的k個數字就是最小的k個數字
【方法三】
建立乙個大小為k的資料容器,用於儲存最小的k個數字。
每次從輸入的n個整數中讀入乙個數,如果容器中已有數字少於k個,則將該數放入容器。
如果容器中已有k個數字,則找出已有k個數中的最大值,與待插入數字做比較,放入更小的數。
因此,在容器已滿時,需要做的事包括:
1)找到最大數
2)刪除最大數
3)插入新數
可用二叉樹來實現該容器,這樣可在o(logk)時間內實現上面步驟,因此對n個輸入數字來說,總時間複雜度o(nlogk)
用二叉樹來實現容器時,由於需要快速找到k個整數的最大數,因此使用最大堆來實現。(找到最大數是因為需要移除最大數)
在最大堆中,根節點的值總是大於它的子樹中的任意節點值。
構造堆/調整堆:
**【方法一】
排序方法在網上挺多的 直接排序之後輸出前k個數字即可
【方法二】
public class q40 ;
int mink = mink(l,5); }
public static int mink(int l,int k)
if(loc=l[loc] && start < end)
int temp = l[end];
l[end--] = l[start];
l[start++] = temp;
} int t = l[end];
l[end] = l[loc];
l[loc] = t;
return end;
}}
【方法三】
public class q40_2 ;
int s = mink(l,5);
showlist(s); }
public static int mink(int l,int k) }
// 調堆
public static void heapify(int i,int l)
if(rightif(i == biggest)
swap(biggest, i, l);
heapify(biggest, l); }
// 交換陣列中兩個數
public static void swap(int i,int j,int l)
// 列印陣列
public static void showlist(int l)
system.out.println();
}}
劍指offer第二版 面試題6(java)
面試題6 從尾到頭列印鍊錶 題目 輸入乙個鍊錶的頭結點,從尾到頭反過來列印出每個結點的值 鍊錶的結點定義如下 public class listnode 注意 面試中,如果打算修改輸入的資料,最好先問好是否資料是允許修改的 思路 1.遍歷順序從頭到尾,列印順序從尾到頭,第乙個結點最開始被訪問,但是最...
劍指offer第二版 面試題8 java
題目描述 給定乙個二叉樹和其中的乙個結點,請找出中序遍歷順序的下乙個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指標 分析 情況 一 有右子樹,這時只需要把其右孩子作為下乙個遍歷的 並不是要找的 節點,然後沿著該節點的左子樹 如果有的話 出發,直到遇到葉子節點,那麼該葉子節...
劍指offer第二版 面試題9(java)
面試題9 用兩個棧實現佇列 題目描述 方法 兩個棧 stack1 stack2 插入時,直接放入stack1 刪除時,直接彈出pop2中的物件 如果pop2為空,則先將pop1中的物件放入stack2中,再從stack2裡pop第乙個 如 依次放入stack1中1 2 3,在彈出並放入stack2中...