在乙個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。
其實這個題目是非常有規律的,所以才可以用複雜度更小的方法來實現。由於其每行自左向右遞增,每列自上而下遞增,所我們可以設定乙個初始位置,讓他不在(0,0)的位置,而是第一列最後乙個位置,如果實際數比它大了,那就向右查詢,否則向上查詢。
bool find(int target, vector> array)
}return false;
}
void replacespace(char *str,int length)
int newlen=realen+count*2;
if(length=0;j--)
}str[newlen]='\0';
}
輸入乙個鍊錶,按煉錶值從尾到頭的順序返回乙個arraylist。
其實很容易想到,可以使用filo的堆疊來進行處理。
vectorprintlistfromtailtohead(listnode* head)
int len= arr.size();
for(int i=0;i輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。
我們根據前序遍歷的特點可以發現,前序遍歷的第乙個數字一定是這個二叉樹的根節點;然後根據中序遍歷的特點可發現,根節點左側的數字一定是左子樹,右側一定是右子樹。然後將中序遍歷以根節點為中心劃分成兩個部分,這又是兩個子樹,然後這個子樹又可以根據前序遍歷找到各個子樹的根節點……以此類推,這非常適合有遞推來實現。
就拿這個例子來說。
前序遍歷:序號0
1234
567內容
1247
3568
中序遍歷:序號0
1234
567內容
4721538
6 這又就把中序遍歷分為了4/7/2和5/3/8/6兩個部分。然後考慮4/7/2這個部分,前序遍歷的第2個數字是劃分4/7/2的數字,這樣,2是這個子樹的根節點,4/7都位於左子樹。
然後再看右子樹,也就是3/5/6/8這四個數字。同理可以得出,3是右子樹的根節點,然後5在左子樹,8/6在右子樹。再去8/6這個子樹看,根據前序遍歷可以看到6為子樹的根節點,根據中序遍歷可以看到,8為子樹的左結點。
接下來考慮**實現問題。首先肯定要判斷所給的兩個陣列是不是空,若是空肯定是個空樹,否則繼續進行。我們可以使用類裡面的乙個私有函式來進行具體的重建功能,而這個函式的引數自然是前序遍歷結果、起始位置、結束位置、中序遍歷結果、起始位置、結束位置。
當然作為剛開始的時候,起始位置肯定是0,結束位置肯定是length-1。
使用這個私有函式進行遞迴,肯定有停止遞迴的條件,那就是開始位置大於結束位置的時候,自然就代表迭代結束了。
然後新建乙個treenode,第乙個節點自然是前序遍歷的第乙個節點,所以可以:
treenode root=new treenode(pre[startpre]);
接下來自然要開始進行判斷,尋找前序遍歷和中序遍歷相等值的位置,由於前序遍歷裡面的點都可以作為中序遍歷裡面的根節點,所以我們只需要在中序遍歷裡面找到與前序遍歷中值相等的位置,就是該子樹的根節點的位置,就可以根據這個點劃分左子樹和右子樹了。而中序遍歷中到的根節點的位置i左側有幾個數字就是左子樹有幾個元素,右邊有幾個數字就是右子樹有幾個元素
對於左子樹來說,左子樹的起始位置自然是startpre的下乙個位置,而結束是startpre+i-startin(startpre是位置,i-startin是從中序遍歷中看左子樹有幾個元素),而中序遍歷的開始位置自然是startin,結束位置是i-1。
對於右子樹來說,中序遍歷的起始位置自然是i+1,結束位置是endin;而對於前序遍歷來說,自然是startpre+左子樹的元素數+1,而左子樹我們知道是i-startin了,所以起始位置是startpre+i-startin+1,結束位置自然是endpre。
於是,完成了這個程式的編寫。
public treenode reconstructbinarytree(int pre,int in)
//前序遍歷和中序遍歷序列
private treenode reconstructbinarytree(int pre,int startpre,int endpre,int in,int startin,int endin)
return root;
}
用兩個棧來實現乙個佇列,完成佇列的push和pop操作。 佇列中的元素為int型別。
思路很簡單,就是用兩個堆疊,push直接push進去就可以。由於佇列是fifo,而堆疊是filo,所以只要使用push後的堆疊再push到另乙個堆疊裡面,這個時候pop出來的順序總體上來說就是fifo了。
public:
void push(int node)
int pop()
int res=stack2.top();
stack2.pop();
return res;}
private:
stackstack1;
stackstack2;
把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入乙個非減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。 例如陣列為的乙個旋轉,該陣列的最小值為1。 note:給出的所有元素都大於0,若陣列大小為0,請返回0。
最傻瓜的方式就是直接進行比較了,但是這樣的時間複雜度為o(n),我們可以考慮降低複雜度。考慮到這個旋轉陣列本質上是乙個基本有序的陣列,所以我們可以考慮借鑑二分查詢的思想。
令low=0,high=len-1,即兩個指標分別指向陣列的開頭和結尾。我們令mid=(low+high)/2。
int minnumberinrotatearray(vectorrotatearray)
return rotatearray[low];
}
給定乙個double型別的浮點數base和int型別的整數exponent。求base的exponent次方。
假如我們要計算313,我們既可以直接乘(複雜度為o(n)),也可以用快速演算法降低複雜度。方法是怎樣的呢?
我們關注指數部分,13=(1101)2所以313=3(1000)2
3(0100)2
3(0001)2
。這樣的話,我們可以將exponent&1操作,如最低位為1,那麼就是做ans=ans * base,否則不做。然後對exponent進行右移,每右移1位,base=base * base,這樣若為1,則ans=base;若為101,則為ans=base * (base * base)。然後就可以得到結果了,**如下。
double power(double base, int exponent)
return exponent<0?(1/ans):ans;
}
劍指offer部分題解(1)
題目描述 輸入乙個正整數陣列,把陣列裡所有數字拼接起來排成乙個數,列印能拼接出的所有數字中最小的乙個。例如輸入陣列,則列印出這三個數字能排成的最小數字為321323。思路 注意點class solution string printminnumber vector int numbers sort ...
劍指offer題解
在乙個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。思路 這題較好的思路有兩個,乙個是最容易想到的nlog,枚舉行,二分列。另一種就是從左下角逐步列舉,如果大於目標值就向上走,小於目標值...
劍指Offer題解索引
陣列中重複的數字 二維陣列中的查詢 構建乘積陣列 替換空格 字元流中第乙個不重複的字元 表示數值的字串 斐波那契數列 跳台階 跳台階 矩形覆蓋 從尾到頭列印鍊錶 刪除鍊錶中重複的結點 鍊錶中環的入口結點 把二叉樹列印成多行 按之字形順序列印二叉樹 對稱的二叉樹 二叉樹的下乙個結點 資料流中的中位數 ...