面試中變相考算法複雜度

一:題目:給定單向鏈表的頭指針和一個結點指針,定義一個函數在O(1)時間刪除該結點。面試

鏈表結點與函數的定義例如如下:算法

struct ListNode
{
    int    m_nValue;
	ListNode* m_pNext;
};

void delete_note(ListNode *head,ListNode *current)
{
	// 空的
	if(head == null || current==null)
	{
		return;
	}
	else if(current->m_pNext != null)
	{// 非結尾
		ListNode *tmp = current->m_pNext;
		current->m_nValue = tmp->m_nValue;
		current->m_pNext = tmp->m_pNext;
		delete tmp;
		tmp = null;
	}
	else if(head == current)
	{// 僅僅有一個節點
		delete current;
		current = null;
		head = null;
	}
	else
	{// 尾節點,不是一個哦
		ListNode *tmp = head;
		while(tmp->m_pNext != current)
			tmp = current->m_pNext;
		tmp->m_pNext = null;
		delete current;
		current = null;
	}
}

分析:假設待刪除節點爲最後一個節點,則不能依照以上思路,沒有辦法,僅僅能依照常規方法遍歷,時間複雜度爲O(n),是否是不符合題目要求呢?可能很是多人在這就會懷疑

本身的思考,從而放棄這樣的思路,最後可能放棄這道題,這就是這道面試題有意思的地方。雖看簡單,但是考察了你們的分析推斷能力,是否擁有強大的心理,充分自信。事實上數組

咱們分析一下,仍然是知足題目要求的。假設刪除節點爲前面的n-1個節點。則時間複雜度爲O(1),僅僅有刪除節點爲最後一個時,時間複雜度才爲O(n),因此平均的時間複雜度函數

爲:(O(1) * (n-1) + O(n))/n = O(1);仍然爲O(1)post

單向鏈表中刪除一個結點,最常規的方法是從頭至尾掃描一遍找到結點,而後刪除結點。對於給定的是值得結點,沒有辦法僅僅能從頭至尾掃描一個一個對照值得大小,假設鏈表學習

中存在。則刪除結點。優化

本題給出的是一個結點的指針,咱們無需掃描就可以獲得結點的指針。在這個過程當中。僅僅要把當前結點(p)的next結點(q)的值賦給當前結點。把q的指針

next結點鏈接到p的next域刪,接下來刪除結點q就知足題目的要求了。code

但是這個題目中存在不少陷阱:首先是邊界條件的考慮。而後是刪除結點的位置,表頭,表尾,和中間,不一樣的地方刪除時處理不同。blog

二:給定一個數組a[N],咱們但願構造數組b[N],當中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。

在構造過程:

一、不一樣意使用除法;

二、要求O(1)空間複雜度和O(n)時間複雜度。

三、除遍歷計數器與a[N] b[N]外,不可以使用新的變量(包含棧暫時變量、對空間和全局靜態變量等);

void makeArray(int a[],int b[],int len)    
{    
    int i,j;    
    b[0] = 1;    
    
    for(i=1;i<len;i++)    
    {    
        b[i] = b[i-1]*a[i-1];   //累乘a[0]*a[1]...a[i-1]    
    }    
    
    b[0] = a[len-1];    
    for(j=len-2;j>0;j--)    
    {    
        b[j] *= b[0];    
        b[0] *= a[j];    
    }    
} 

學習心得 1  對於這樣的帶要求的(要求苛刻的)問題,就要求咱們不能應用常規的方法來思考它。 2  這樣的題,通常有一些特色,裏面的技巧性很是強。固然也比較easy發現,從遞推公式中可以看出一些端倪; 3  你用常規的方法書寫時 再加上 從遞推公式中可以看出一些端倪 應該不難看出它的解法 4  平時必定要多多練習。在本身高速地寫完一個算法題後,想想有沒有更優的方法,哪怕僅僅有一點點代碼優化; 5 代碼優化,也是在面試的時候面試官,在你寫完代碼後,最愛問的一個問題。
相關文章
相關標籤/搜索