1. 程式人生 > >幾種有關排序的常見面試問題

幾種有關排序的常見面試問題

1、荷蘭國旗問題

題目描述:現有n個紅白藍三種不同顏色的小球,亂序排列在一起,請通過兩兩交換任意兩個球,使得從左至右,依次是一些紅球、一些白球、一些藍球。

分析與解法:

初看此題,我們貌似除了暴力解決並無好的辦法,但聯想到我們所熟知的快速排序演算法呢?

我們知道,快速排序依託於一個partition分治過程,在每一趟排序的過程中,選取的主元都會把整個陣列排列成一大一小的部分,那我們是否可以借鑑partition過程設定三個指標完成重新排列,使得所有球排列成三個不同顏色的球呢?

解法:

通過前面的分析得知,這個問題類似快排中partition過程,只是需要用到三個指標:一個前指標begin,一箇中指標current,一個後指標end,current指標遍歷整個陣列序列,當

1.current指標所指元素為0時,與begin指標所指的元素交換,而後current++,begin++ ;
2.current指標所指元素為1時,不做任何交換(即球不動),而後current++ ;
3.current指標所指元素為2時,與end指標所指的元素交換,而後,current指標不動,end– 。

為什麼上述第3點中,current指標所指元素為2時,與end指標所指元素交換之後,current指標不能動呢?因為第三步中current指標所指元素與end指標所指元素交換之前,如果end指標之前指的元素是0,那麼與current指標所指元素交換之後,current指標此刻所指的元素是0,此時,current指標能動麼?不能動,因為如上述第1點所述,如果current指標所指的元素是0,還得與begin指標所指的元素交換。

ok,說這麼多,你可能不甚明瞭,直接引用下gnuhpc的圖,就一目瞭然了:

這裡寫圖片描述

參考程式碼如下:

#include<iostream>
#include<vector>
using namespace std;
class ThreeColor {
public:
    vector<int> sortThreeColor(vector<int> &A, int n)
    {
        int f,r,i,temp;
        for(i=f=0,r=n-1;i<=r;i++)
        {
            if
(A[i]==0) { temp=A[f]; A[f]=A[i]; A[i]=temp; f++; } if(A[i]==2) { temp=A[r]; A[r]=A[i]; A[i]=temp; r--; i--; } } return A; } }; int main() { int a[6]={1,2,0,2}; vector<int> b(a,a+4); ThreeColor c; c.sortThreeColor(b,4); for(int i=0;i<4;i++) cout<<b[i]<<" "; cout<<endl; return 0; }

2、求需要排序的最短子陣列長度

題目描述:
假設陣列為a b c d e f g h i j k l m n,

如果abc是有序的,mn是有序的,至於中間的defghijkl是無序的,我們可以得知,如果是正常升序序列,左邊的一定是小於右邊的任意數值,右邊的一定大於左邊的任意數值。

思路:

1、我們從後往前遍歷,如果某個元素大於右邊最小的元素,就標記,一直遍歷到最左邊;
2、從前往後遍歷,如果某個元素小於左邊的最大的元素,則標記,一直遍歷到最右邊。

參考程式碼:

#include<iostream>
#include<vector>
using namespace std;
class Subsequence {
public:
    int shortestSubsequence(vector<int> A, int n) 
    {
        int max=A[0],min=A[n-1],i,rd1,rd2;
        for(i=1,rd1=0;i<n;i++)
        {
            if(A[i]>=max)
                max=A[i];
            else
                rd1=i;
        }
        for(i=n-2,rd2=n-1;i>=0;i--)
        {
            if(A[i]<=min)
                min=A[i];
            else
                rd2=i;
        }
        if(!rd1)
            return 0;
        else
            return rd1-rd2+1;
    }
};
int main()
{
    int a[6]={1,4,6,5,9,10};
    vector<int> b(a,a+6);
    Subsequence c;
    int d=c.shortestSubsequence(b,6);
    cout<<d<<endl;
    return 0;
}

相關推薦

有關排序常見面試問題

1、荷蘭國旗問題 題目描述:現有n個紅白藍三種不同顏色的小球,亂序排列在一起,請通過兩兩交換任意兩個球,使得從左至右,依次是一些紅球、一些白球、一些藍球。 分析與解法: 初看此題,我們貌似除了暴力解決並無好的辦法,但聯想到我們所熟知的快速排序演算法呢?

常見陣列排序方法

---恢復內容開始--- 一、研究陣列排序的意義: 資料結構中,排序演算法各有用處,不同的排序方法有不同的時間複雜度與空間複雜度。為了能夠依據不同情況,選用不同的排序方法解決不同的問題。 二、常見的陣列排序方法: 以下研究,預設是對運算元組進行從小到大的排序。使用語言是Java。 1.選擇排序法

C#中常見陣列排序例項

1、氣泡排序冒泡是最常用的排序方法之一,它在第一次排序的時候將每一條記錄的關鍵字進行比較,直到n-1個記錄和n個記錄的關鍵字比較完成為止,再進行下一次排序,直到n-1趟記錄為止 class BubbleSorter /// <summary

常見排序演算法以及實現(C語言)

所有未排序的陣列是經過檢查合法的 主要的內排序包括冒泡、插入、希爾、堆排序、歸併、快速、桶排序等 其C語言實現的原始檔下載地址:http://download.csdn.net/detail/mcu_tian/9530227 氣泡排序 氣泡排序應該是排序中最簡單的演算法了

基本排序算法總結

子序列 system aop 大於等於 != pri i++ index 元素移動 以下均采用從小到大排序: 1.選擇排序算法 個人覺得選擇排序算法是容易理解的排序算法,即從n個元素中選擇最小的一個元素與第一個元素交換,再將除第一個元素之外的n-1個元素找到最小的一

常用排序算法 (一)

實現 void 交換 完成 快速 並排 元素 [] log 八大常用排序算法詳細分析 包括復雜度: 排序有可以分為以下幾類: (1)、交換排序:冒泡排序、快速排序 (2)、選擇排序:直接選擇排序、堆排序 (3)、插入排序:直接插入排序、希爾排序 (4)、歸並排序 (5)、

常用排序演算法的思路和複雜度對比

1、插入排序——直接插入排序、希爾排序 (1)直接插入排序思路:從第1號元素開始,每個元素依次與前面的元素做比較,小的排前面,這樣當比較到最後一 個元 素完即完成排序。 (2)希爾排序思路:     

初級排序演算法的總結

@TOC 幾種初級排序演算法的總結 排序就是將一組物件按照某種邏輯順序重新排列的過程。 在本文中我們使用的操作: 遍歷陣列 比較兩個物件(本文中所有程式碼示例中的less方法) 交換兩個物件 (本文中所有程式碼示例中的

常用排序演算法總結

選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法,氣泡排序、插入排序、歸併排序和基數排序是穩定的排序演算法。 冒泡法:  這是最原始,也是眾所周知的最慢的演算法了。他的名字的由來因為它的工作看來象是冒泡:  複雜度為O(n*n)。當資料為正序,將不會有交換。複雜度為

經典排序演算法的JS實現方法+隨機洗牌演算法

一.氣泡排序functionBubbleSort(array) { var length = array.length; for(var i = length - 1; i > 0; i--) { //用於縮小範圍 for(var j = 0; j

java實現常用排序:選擇排序

一.選擇排序介紹 選擇排序,顧名思義就是用逐個選擇的方式來進行排序,逐個選擇出陣列中的最大(或最小)的元素,直到選擇至最後一個元素。此時陣列完成了排序。 二.選擇排序原理分析 三.選擇排序程式碼實現 /** * @Author {LearnAndGet} * @Time 2019年1月8日

python經典排序方法的實現

程式碼已封裝為SortMethod的class #*-* coding:utf-8 *-* ''' Author:7a6d4 calss for sorting ''' class SortMethod: ''' 插入排序的基本操作就是將一個

Andorid中簡單又常見的ListView的優化方案!

Android中的ListView應該算是佈局中幾種最常用的元件之一了,使用也十分方便,下面將介紹ListView幾種比較常見的優化方法: 首先我們給出一個沒有任何優化的Listview的Adapter類,我們這裡都繼承自BaseAdapter,這裡我們使用一個包含10

內部排序演算法

通常說的排序指: ①.內部排序演算法(資料在記憶體中進行排序) ②.外部排序演算法(資料大,需要訪問外存) 我們把排序進行了劃分,並計算出排序的時間複雜度,穩定性;下來逐個對排序演算法實現,並歸納出排序的實現過程和思想。 插入類排序 插入類

排序演算法--插入排序

    插入排序總體上說也是簡單排序,除去Shell排序的話,其他的插入排序演算法時間複雜度基本上是O(n ^ 2)的,除非有特殊的情況.     首先說說直接插入排序: 描述:     插入排序的思想大概就像是打牌是摸牌的過程(很多書諸如<<演算法導論>&

機器學習常見的距離

歐氏距離:最為常見,可以理解為歐式空間裡兩點的直線距離。 兩個點 A = (a[1],a[2],…,a[n]) 和 B = (b[1],b[2],…,b[n]) 之間的距離 ρ(A,B) 定義為下面的公式: ρ(A,B) =√ [ ∑( a[i] - b[i] )^2 ]

java基礎之常見排序算法

java基礎 csdn n) min center 最小 fill 順序 system 一,冒泡排序 1、原理:   從數組的第一個位置開始兩兩比較array[index]和array[index+1],如果array[index]大於array[index+1]則交換a

【知了堂學習筆記】java 編寫常見排序算法

第一個 public 調用 ati print 所有 eth string quick 排序的分類: 一.交換排序 所謂交換,就是根據序列中兩個記錄鍵值的比較結果來對換這兩個記錄在序列中的位置,交換排序的特點是:將鍵值較大的記錄向序列的尾部移動,鍵值較小的記錄向序列的前部

PHP常見排序算法

php 算法 排序 冒泡排序 一、冒泡排序排序原理:對一組數據,比較相鄰數據的大小,把小的數據放在前面,值大的放在後面(升序排序)舉例說明: $arr = [6, 3, 8, 2, 9, 1];第一輪排序: 第一次比較 6和3比較: 3 6 8 2 9 1

資料結構 之 常見排序

排序(sorting)是演算法家族裡比較重要也比較基礎的一類,內容也是五花八門了: 1、有“基於比較”的,也有“不基於比較”的; 2、有迭代的(iterative)也有遞迴的(recursive); 3、有利用分治法(divide and conquer)思路解決的;(除了顯而易見的“二路歸併”演算法,“代入