劍指offer第二版 面試題40(java)

2021-09-22 18:51:27 字數 1580 閱讀 1104

面試題:最小的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中...