力扣OJ 劍指 Offer(31-68)
目錄
劍指 Offer 31. 棧的壓入、彈出序列 946. 驗證棧序列
劍指 Offer 34. 二叉樹中和為某一值的路徑 113. 路徑總和 II
劍指 Offer 35. 複雜連結串列的複製 138. 複製帶隨機指標的連結串列
劍指 Offer 39. 陣列中出現次數超過一半的數字 169. 多數元素
劍指 Offer 42. 連續子陣列的最大和 53. 最大子序和
劍指 Offer 48. 最長不含重複字元的子字串 3. 無重複字元的最長子串
劍指 Offer 51. 陣列中的逆序對(離散化+sum型線段樹)
劍指 Offer 52. 兩個連結串列的第一個公共節點 160. 相交連結串列
劍指 Offer 53 - I. 在排序陣列中查詢數字 I 34. 在排序陣列中查詢元素的第一個和最後一個位置
劍指 Offer 55 - I. 二叉樹的深度 104. 二叉樹的最大深度
劍指 Offer 55 - II. 平衡二叉樹 110. 平衡二叉樹
劍指 Offer 56 - I. 陣列中數字出現的次數(尋找僅出現一次的2個數)
劍指 Offer 56 - II. 陣列中數字出現的次數 II(三進位制異或)
劍指 Offer 58 - I. 翻轉單詞順序 151. 翻轉字串裡的單詞
劍指 Offer 63. 股票的最大利潤 121. 買賣股票的最佳時機
劍指 Offer 67. 把字串轉換成整數 8. 字串轉換整數 (atoi)
劍指 Offer 68 - I. 235. 二叉搜尋樹的最近公共祖先
劍指 Offer 68 - II. 236. 二叉樹的最近公共祖先
劍指 Offer 31. 棧的壓入、彈出序列 946. 驗證棧序列
給定pushed和popped兩個序列,每個序列中的 值都不重複,只有當它們可能是在最初空棧上進行的推入 push 和彈出 pop 操作序列的結果時,返回 true;否則,返回 false。
示例 1:
輸入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
輸出:true
解釋:我們可以按以下順序執行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:
輸入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
輸出:false
解釋:1 不能在 2 之前彈出。
提示:
0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed是popped的排列。
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int>s;
int pushid=0,popid=0;
while(pushid<pushed.size())
{
s.push(pushed[pushid++]);
while(!s.empty() && s.top()==popped[popid])
{
s.pop();
popid++;
}
}
return s.empty();
}
};
劍指 Offer 33. 二叉搜尋樹的後序遍歷序列
輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷結果。如果是則返回true,否則返回false。假設輸入的陣列的任意兩個數字都互不相同。
參考以下這顆二叉搜尋樹:
5
/ \
2 6
/ \
1 3
示例 1:
輸入: [1,6,3,2,5]
輸出: false
示例 2:
輸入: [1,3,2,6,5]
輸出: true
提示:
陣列長度 <= 1000
class Solution {
public:
bool verifyPostorder(vector<int>& postorder,int x,int y) {
if(x>=y)return true;
int k=postorder[y];
int loc=x;
while(loc<y && postorder[loc]<k)loc++;
for(int i=loc;i<y;i++)if(postorder[i]<k)return false;
return verifyPostorder(postorder,x,loc-1) && verifyPostorder(postorder,loc,y-1);
}
bool verifyPostorder(vector<int>& postorder) {
if(postorder.size()==0)return true;
return verifyPostorder(postorder,0,postorder.size()-1);
}
};
劍指 Offer 34. 二叉樹中和為某一值的路徑 113. 路徑總和 II
題目:
給定一個二叉樹和一個目標和,找到所有從根節點到葉子節點路徑總和等於給定目標和的路徑。
說明:葉子節點是指沒有子節點的節點。
示例:
給定如下二叉樹,以及目標和sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
程式碼:
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<int>tmp;
vector<vector<int>>ans;
if (!root)return ans;
if (!root->left && !root->right)
{
if (sum == root->val)
{
tmp.insert(tmp.end(), sum);
ans.insert(ans.end(), tmp);
}
return ans;
}
ans = pathSum(root->left, sum - root->val);
vector<vector<int>>ans2 = pathSum(root->right, sum - root->val);
for (int i = 0; i < ans2.size(); i++)
{
ans.insert(ans.end(), ans2[i]);
}
for (int i = 0; i < ans.size(); i++)
{
ans[i].insert(ans[i].begin(), root->val);
}
return ans;
}
};
劍指 Offer 35. 複雜連結串列的複製 138. 複製帶隨機指標的連結串列
題目:
給定一個連結串列,每個節點包含一個額外增加的隨機指標,該指標可以指向連結串列中的任何節點或空節點。
要求返回這個連結串列的深拷貝。
我們用一個由n個節點組成的連結串列來表示輸入/輸出中的連結串列。每個節點用一個[val, random_index]表示:
val:一個表示Node.val的整數。
random_index:隨機指標指向的節點索引(範圍從0到n-1);如果不指向任何節點,則為null。
示例 1:
輸入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
輸出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
輸入:head = [[1,1],[2,1]]
輸出:[[1,1],[2,1]]
示例 3:
輸入:head = [[3,null],[3,0],[3,null]]
輸出:[[3,null],[3,0],[3,null]]
示例 4:
輸入:head = []
輸出:[]
解釋:給定的連結串列為空(空指標),因此返回 null。
提示:
-10000 <= Node.val <= 10000
Node.random為空(null)或指向連結串列中的節點。
節點數目不超過 1000 。
程式碼:
class Solution {
public:
Node* copyRandomList(Node* head) {
if (!head)return NULL;
Node* p = head;
map<Node*, Node*>m;
while (p)
{
Node* tmp = new Node(p->val);
m[p] = tmp, p = p->next;
}
p = head;
while (p)
{
m[p]->next = m[p->next], m[p]->random = m[p->random], p = p->next;
}
return m[head];
}
};
劍指 Offer 36. 二叉搜尋樹與雙向連結串列
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的迴圈雙向連結串列。要求不能建立任何新的節點,只能調整樹中節點指標的指向。
為了讓您更好地理解問題,以下面的二叉搜尋樹為例:
我們希望將這個二叉搜尋樹轉化為雙向迴圈連結串列。連結串列中的每個節點都有一個前驅和後繼指標。對於雙向迴圈連結串列,第一個節點的前驅是最後一個節點,最後一個節點的後繼是第一個節點。
下圖展示了上面的二叉搜尋樹轉化成的連結串列。“head” 表示指向連結串列中有最小元素的節點。
特別地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指標需要指向前驅,樹中節點的右指標需要指向後繼。還需要返回連結串列中的第一個節點的指標。
//建立單節點雙向迴圈連結串列
void getList(Node* p)
{
p->left=p,p->right=p;
}->right=list,list->left=p;
}
//合併雙向迴圈連結串列
void merge2list(Node* p1,Node* p2)
{
p1->left->right=p2,p2->left->right=p1;
Node* tmp=p2->left;
p2->left = p1->left;
p1->left = tmp;
}
class Solution {
public:
Node* treeToDoublyList(Node* root) {
if(root==NULL)return NULL;
Node* l =root->left,*r=root->right;
getList(root);
if(r)merge2list(root,treeToDoublyList(r));
if(!l)return root;
Node* p=treeToDoublyList(l);
merge2list(p,root);
return p;
}
};
劍指 Offer 39. 陣列中出現次數超過一半的數字 169. 多數元素
陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。
你可以假設陣列是非空的,並且給定的陣列總是存在多數元素。
示例1:
輸入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
輸出: 2
限制:
1 <= 陣列長度 <= 50000
class Solution {
public:
int majorityElement(vector<int>& nums) {
int k=nums[0],s=1,loc=0;
while(++loc<nums.size())
{
if(k==nums[loc])s++;
else s--;
if(s==0)k=nums[++loc],s=1;
}
return k;
}
};
劍指 Offer 42. 連續子陣列的最大和 53. 最大子序和
題目:
給定一個整數陣列 nums,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。
示例:
輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋:連續子陣列[4,-1,2,1] 的和最大,為6。
進階:
如果你已經實現複雜度為 O(n) 的解法,嘗試使用更為精妙的分治法求解。
程式碼:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n = nums.size();
if (n == 0)return 0;
int maxs = nums[0];
for (int i = 1; i < n; i++)
{
if (nums[i - 1] > 0)nums[i] += nums[i - 1];
maxs = max(maxs, nums[i]);
}
return maxs;
}
};
劍指 Offer 45. 把陣列排成最小的數(貪心)
輸入一個非負整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。
示例 1:
輸入: [10,2]
輸出: "102"
示例2:
輸入: [3,30,34,5,9]
輸出: "3033459"
提示:
0 < nums.length <= 100
說明:
輸出結果可能非常大,所以你需要返回一個字串而不是整數
拼接起來的數字可能會有前導 0,最後結果不需要去掉前導 0
思路:
其實就是把字串排序一下,然後拼接起來即可,排序規則也很巧妙,見cmp函式
char* itoa(int num,char* str,int radix) //copy from 百度百科
{/*索引表*/
char index[]="0123456789ABCDEF";
unsigned unum;/*中間變數*/
int i=0,j,k;
/*確定unum的值*/
if(radix==10&&num<0)/*十進位制負數*/
{
unum=(unsigned)-num;
str[i++]='-';
}
else unum=(unsigned)num;/*其他情況*/
/*轉換*/
do{
str[i++]=index[unum%(unsigned)radix];
unum/=radix;
}while(unum);
str[i]='\0';
/*逆序*/
if(str[0]=='-') k=1;/*十進位制負數*/
else k=0;
for(j=k;j<=(i-1)/2;j++)
{
char temp;
temp=str[j];
str[j]=str[i-1+k-j];
str[i-1+k-j]=temp;
}
return str;
}
bool cmp(string s1,string s2)
{
return s1+s2<s2+s1;
}
class Solution {
public:
string minNumber(vector<int>& nums) {
vector<string>s(nums.size());
for(int i=0;i<s.size();i++)
{
char *p = (char *)malloc(10);
itoa(nums[i],p,10);
string str(p,p+strlen(p));
s[i]=str;
}
sort(s.begin(),s.end(),cmp);
string ans;
for(int i=0;i<s.size();i++)ans+=s[i];
return ans;
}
};
劍指 Offer 48. 最長不含重複字元的子字串 3. 無重複字元的最長子串
題目:
給定一個字串,請你找出其中不含有重複字元的最長子串的長度。
示例1:
輸入: "abcabcbb"
輸出: 3
解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 因為無重複字元的最長子串是 "b",所以其長度為 1。
示例 3:
輸入: "pwwkew"
輸出: 3
解釋: 因為無重複字元的最長子串是"wke",所以其長度為 3。
請注意,你的答案必須是 子串 的長度,"pwke"是一個子序列,不是子串。
程式碼:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s=="")return 0;
int ans=1,left=0;
for(int i=0;i<s.length();i++){
for(int j=left;j<i;j++)if(s[j]==s[i])left=j+1;
ans=max(ans,i-left+1);
}
return ans;
}
};
劍指 Offer 49. 醜數 264. 醜數 II
題目:
編寫一個程式,找出第 n 個醜數。
醜數就是隻包含質因數2, 3, 5 的正整數。
示例:
輸入: n = 10
輸出: 12
解釋: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 個醜數。
說明:
1是醜數。
n不超過1690。
程式碼:
int ans[] = { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192, 200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384, 400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675, 720, 729, 750, 768, 800, 810, 864, 900, 960, 972, 1000, 1024, 1080, 1125, 1152, 1200, 1215, 1250, 1280, 1296, 1350, 1440, 1458, 1500, 1536, 1600, 1620, 1728, 1800, 1875, 1920, 1944, 2000, 2025, 2048, 2160, 2187, 2250, 2304, 2400, 2430, 2500, 2560, 2592, 2700, 2880, 2916, 3000, 3072, 3125, 3200, 3240, 3375, 3456, 3600, 3645, 3750, 3840, 3888, 4000, 4050, 4096, 4320, 4374, 4500, 4608, 4800, 4860, 5000, 5120, 5184, 5400, 5625, 5760, 5832, 6000, 6075, 6144, 6250, 6400, 6480, 6561, 6750, 6912, 7200, 7290, 7500, 7680, 7776, 8000, 8100, 8192, 8640, 8748, 9000, 9216, 9375, 9600, 9720, 10000, 10125, 10240, 10368, 10800, 10935, 11250, 11520, 11664, 12000, 12150, 12288, 12500, 12800, 12960, 13122, 13500, 13824, 14400, 14580, 15000, 15360, 15552, 15625, 16000, 16200, 16384, 16875, 17280, 17496, 18000, 18225, 18432, 18750, 19200, 19440, 19683, 20000, 20250, 20480, 20736, 21600, 21870, 22500, 23040, 23328, 24000, 24300, 24576, 25000, 25600, 25920, 26244, 27000, 27648, 28125, 28800, 29160, 30000, 30375, 30720, 31104, 31250, 32000, 32400, 32768, 32805, 33750, 34560, 34992, 36000, 36450, 36864, 37500, 38400, 38880, 39366, 40000, 40500, 40960, 41472, 43200, 43740, 45000, 46080, 46656, 46875, 48000, 48600, 49152, 50000, 50625, 51200, 51840, 52488, 54000, 54675, 55296, 56250, 57600, 58320, 59049, 60000, 60750, 61440, 62208, 62500, 64000, 64800, 65536, 65610, 67500, 69120, 69984, 72000, 72900, 73728, 75000, 76800, 77760, 78125, 78732, 80000, 81000, 81920, 82944, 84375, 86400, 87480, 90000, 91125, 92160, 93312, 93750, 96000, 97200, 98304, 98415, 100000, 101250, 102400, 103680, 104976, 108000, 109350, 110592, 112500, 115200, 116640, 118098, 120000, 121500, 122880, 124416, 125000, 128000, 129600, 131072, 131220, 135000, 138240, 139968, 140625, 144000, 145800, 147456, 150000, 151875, 153600, 155520, 156250, 157464, 160000, 162000, 163840, 164025, 165888, 168750, 172800, 174960, 177147, 180000, 182250, 184320, 186624, 187500, 192000, 194400, 196608, 196830, 200000, 202500, 204800, 207360, 209952, 216000, 218700, 221184, 225000, 230400, 233280, 234375, 236196, 240000, 243000, 245760, 248832, 250000, 253125, 256000, 259200, 262144, 262440, 270000, 273375, 276480, 279936, 281250, 288000, 291600, 294912, 295245, 300000, 303750, 307200, 311040, 312500, 314928, 320000, 324000, 327680, 328050, 331776, 337500, 345600, 349920, 354294, 360000, 364500, 368640, 373248, 375000, 384000, 388800, 390625, 393216, 393660, 400000, 405000, 409600, 414720, 419904, 421875, 432000, 437400, 442368, 450000, 455625, 460800, 466560, 468750, 472392, 480000, 486000, 491520, 492075, 497664, 500000, 506250, 512000, 518400, 524288, 524880, 531441, 540000, 546750, 552960, 559872, 562500, 576000, 583200, 589824, 590490, 600000, 607500, 614400, 622080, 625000, 629856, 640000, 648000, 655360, 656100, 663552, 675000, 691200, 699840, 703125, 708588, 720000, 729000, 737280, 746496, 750000, 759375, 768000, 777600, 781250, 786432, 787320, 800000, 810000, 819200, 820125, 829440, 839808, 843750, 864000, 874800, 884736, 885735, 900000, 911250, 921600, 933120, 937500, 944784, 960000, 972000, 983040, 984150, 995328, 1000000, 1012500, 1024000, 1036800, 1048576, 1049760, 1062882, 1080000, 1093500, 1105920, 1119744, 1125000, 1152000, 1166400, 1171875, 1179648, 1180980, 1200000, 1215000, 1228800, 1244160, 1250000, 1259712, 1265625, 1280000, 1296000, 1310720, 1312200, 1327104, 1350000, 1366875, 1382400, 1399680, 1406250, 1417176, 1440000, 1458000, 1474560, 1476225, 1492992, 1500000, 1518750, 1536000, 1555200, 1562500, 1572864, 1574640, 1594323, 1600000, 1620000, 1638400, 1640250, 1658880, 1679616, 1687500, 1728000, 1749600, 1769472, 1771470, 1800000, 1822500, 1843200, 1866240, 1875000, 1889568, 1920000, 1944000, 1953125, 1966080, 1968300, 1990656, 2000000, 2025000, 2048000, 2073600, 2097152, 2099520, 2109375, 2125764, 2160000, 2187000, 2211840, 2239488, 2250000, 2278125, 2304000, 2332800, 2343750, 2359296, 2361960, 2400000, 2430000, 2457600, 2460375, 2488320, 2500000, 2519424, 2531250, 2560000, 2592000, 2621440, 2624400, 2654208, 2657205, 2700000, 2733750, 2764800, 2799360, 2812500, 2834352, 2880000, 2916000, 2949120, 2952450, 2985984, 3000000, 3037500, 3072000, 3110400, 3125000, 3145728, 3149280, 3188646, 3200000, 3240000, 3276800, 3280500, 3317760, 3359232, 3375000, 3456000, 3499200, 3515625, 3538944, 3542940, 3600000, 3645000, 3686400, 3732480, 3750000, 3779136, 3796875, 3840000, 3888000, 3906250, 3932160, 3936600, 3981312, 4000000, 4050000, 4096000, 4100625, 4147200, 4194304, 4199040, 4218750, 4251528, 4320000, 4374000, 4423680, 4428675, 4478976, 4500000, 4556250, 4608000, 4665600, 4687500, 4718592, 4723920, 4782969, 4800000, 4860000, 4915200, 4920750, 4976640, 5000000, 5038848, 5062500, 5120000, 5184000, 5242880, 5248800, 5308416, 5314410, 5400000, 5467500, 5529600, 5598720, 5625000, 5668704, 5760000, 5832000, 5859375, 5898240, 5904900, 5971968, 6000000, 6075000, 6144000, 6220800, 6250000, 6291456, 6298560, 6328125, 6377292, 6400000, 6480000, 6553600, 6561000, 6635520, 6718464, 6750000, 6834375, 6912000, 6998400, 7031250, 7077888, 7085880, 7200000, 7290000, 7372800, 7381125, 7464960, 7500000, 7558272, 7593750, 7680000, 7776000, 7812500, 7864320, 7873200, 7962624, 7971615, 8000000, 8100000, 8192000, 8201250, 8294400, 8388608, 8398080, 8437500, 8503056, 8640000, 8748000, 8847360, 8857350, 8957952, 9000000, 9112500, 9216000, 9331200, 9375000, 9437184, 9447840, 9565938, 9600000, 9720000, 9765625, 9830400, 9841500, 9953280, 10000000, 10077696, 10125000, 10240000, 10368000, 10485760, 10497600, 10546875, 10616832, 10628820, 10800000, 10935000, 11059200, 11197440, 11250000, 11337408, 11390625, 11520000, 11664000, 11718750, 11796480, 11809800, 11943936, 12000000, 12150000, 12288000, 12301875, 12441600, 12500000, 12582912, 12597120, 12656250, 12754584, 12800000, 12960000, 13107200, 13122000, 13271040, 13286025, 13436928, 13500000, 13668750, 13824000, 13996800, 14062500, 14155776, 14171760, 14348907, 14400000, 14580000, 14745600, 14762250, 14929920, 15000000, 15116544, 15187500, 15360000, 15552000, 15625000, 15728640, 15746400, 15925248, 15943230, 16000000, 16200000, 16384000, 16402500, 16588800, 16777216, 16796160, 16875000, 17006112, 17280000, 17496000, 17578125, 17694720, 17714700, 17915904, 18000000, 18225000, 18432000, 18662400, 18750000, 18874368, 18895680, 18984375, 19131876, 19200000, 19440000, 19531250, 19660800, 19683000, 19906560, 20000000, 20155392, 20250000, 20480000, 20503125, 20736000, 20971520, 20995200, 21093750, 21233664, 21257640, 21600000, 21870000, 22118400, 22143375, 22394880, 22500000, 22674816, 22781250, 23040000, 23328000, 23437500, 23592960, 23619600, 23887872, 23914845, 24000000, 24300000, 24576000, 24603750, 24883200, 25000000, 25165824, 25194240, 25312500, 25509168, 25600000, 25920000, 26214400, 26244000, 26542080, 26572050, 26873856, 27000000, 27337500, 27648000, 27993600, 28125000, 28311552, 28343520, 28697814, 28800000, 29160000, 29296875, 29491200, 29524500, 29859840, 30000000, 30233088, 30375000, 30720000, 31104000, 31250000, 31457280, 31492800, 31640625, 31850496, 31886460, 32000000, 32400000, 32768000, 32805000, 33177600, 33554432, 33592320, 33750000, 34012224, 34171875, 34560000, 34992000, 35156250, 35389440, 35429400, 35831808, 36000000, 36450000, 36864000, 36905625, 37324800, 37500000, 37748736, 37791360, 37968750, 38263752, 38400000, 38880000, 39062500, 39321600, 39366000, 39813120, 39858075, 40000000, 40310784, 40500000, 40960000, 41006250, 41472000, 41943040, 41990400, 42187500, 42467328, 42515280, 43046721, 43200000, 43740000, 44236800, 44286750, 44789760, 45000000, 45349632, 45562500, 46080000, 46656000, 46875000, 47185920, 47239200, 47775744, 47829690, 48000000, 48600000, 48828125, 49152000, 49207500, 49766400, 50000000, 50331648, 50388480, 50625000, 51018336, 51200000, 51840000, 52428800, 52488000, 52734375, 53084160, 53144100, 53747712, 54000000, 54675000, 55296000, 55987200, 56250000, 56623104, 56687040, 56953125, 57395628, 57600000, 58320000, 58593750, 58982400, 59049000, 59719680, 60000000, 60466176, 60750000, 61440000, 61509375, 62208000, 62500000, 62914560, 62985600, 63281250, 63700992, 63772920, 64000000, 64800000, 65536000, 65610000, 66355200, 66430125, 67108864, 67184640, 67500000, 68024448, 68343750, 69120000, 69984000, 70312500, 70778880, 70858800, 71663616, 71744535, 72000000, 72900000, 73728000, 73811250, 74649600, 75000000, 75497472, 75582720, 75937500, 76527504, 76800000, 77760000, 78125000, 78643200, 78732000, 79626240, 79716150, 80000000, 80621568, 81000000, 81920000, 82012500, 82944000, 83886080, 83980800, 84375000, 84934656, 85030560, 86093442, 86400000, 87480000, 87890625, 88473600, 88573500, 89579520, 90000000, 90699264, 91125000, 92160000, 93312000, 93750000, 94371840, 94478400, 94921875, 95551488, 95659380, 96000000, 97200000, 97656250, 98304000, 98415000, 99532800, 100000000, 100663296, 100776960, 101250000, 102036672, 102400000, 102515625, 103680000, 104857600, 104976000, 105468750, 106168320, 106288200, 107495424, 108000000, 109350000, 110592000, 110716875, 111974400, 112500000, 113246208, 113374080, 113906250, 114791256, 115200000, 116640000, 117187500, 117964800, 118098000, 119439360, 119574225, 120000000, 120932352, 121500000, 122880000, 123018750, 124416000, 125000000, 125829120, 125971200, 126562500, 127401984, 127545840, 128000000, 129140163, 129600000, 131072000, 131220000, 132710400, 132860250, 134217728, 134369280, 135000000, 136048896, 136687500, 138240000, 139968000, 140625000, 141557760, 141717600, 143327232, 143489070, 144000000, 145800000, 146484375, 147456000, 147622500, 149299200, 150000000, 150994944, 151165440, 151875000, 153055008, 153600000, 155520000, 156250000, 157286400, 157464000, 158203125, 159252480, 159432300, 160000000, 161243136, 162000000, 163840000, 164025000, 165888000, 167772160, 167961600, 168750000, 169869312, 170061120, 170859375, 172186884, 172800000, 174960000, 175781250, 176947200, 177147000, 179159040, 180000000, 181398528, 182250000, 184320000, 184528125, 186624000, 187500000, 188743680, 188956800, 189843750, 191102976, 191318760, 192000000, 194400000, 195312500, 196608000, 196830000, 199065600, 199290375, 200000000, 201326592, 201553920, 202500000, 204073344, 204800000, 205031250, 207360000, 209715200, 209952000, 210937500, 212336640, 212576400, 214990848, 215233605, 216000000, 218700000, 221184000, 221433750, 223948800, 225000000, 226492416, 226748160, 227812500, 229582512, 230400000, 233280000, 234375000, 235929600, 236196000, 238878720, 239148450, 240000000, 241864704, 243000000, 244140625, 245760000, 246037500, 248832000, 250000000, 251658240, 251942400, 253125000, 254803968, 255091680, 256000000, 258280326, 259200000, 262144000, 262440000, 263671875, 265420800, 265720500, 268435456, 268738560, 270000000, 272097792, 273375000, 276480000, 279936000, 281250000, 283115520, 283435200, 284765625, 286654464, 286978140, 288000000, 291600000, 292968750, 294912000, 295245000, 298598400, 300000000, 301989888, 302330880, 303750000, 306110016, 307200000, 307546875, 311040000, 312500000, 314572800, 314928000, 316406250, 318504960, 318864600, 320000000, 322486272, 324000000, 327680000, 328050000, 331776000, 332150625, 335544320, 335923200, 337500000, 339738624, 340122240, 341718750, 344373768, 345600000, 349920000, 351562500, 353894400, 354294000, 358318080, 358722675, 360000000, 362797056, 364500000, 368640000, 369056250, 373248000, 375000000, 377487360, 377913600, 379687500, 382205952, 382637520, 384000000, 387420489, 388800000, 390625000, 393216000, 393660000, 398131200, 398580750, 400000000, 402653184, 403107840, 405000000, 408146688, 409600000, 410062500, 414720000, 419430400, 419904000, 421875000, 424673280, 425152800, 429981696, 430467210, 432000000, 437400000, 439453125, 442368000, 442867500, 447897600, 450000000, 452984832, 453496320, 455625000, 459165024, 460800000, 466560000, 468750000, 471859200, 472392000, 474609375, 477757440, 478296900, 480000000, 483729408, 486000000, 488281250, 491520000, 492075000, 497664000, 500000000, 503316480, 503884800, 506250000, 509607936, 510183360, 512000000, 512578125, 516560652, 518400000, 524288000, 524880000, 527343750, 530841600, 531441000, 536870912, 537477120, 540000000, 544195584, 546750000, 552960000, 553584375, 559872000, 562500000, 566231040, 566870400, 569531250, 573308928, 573956280, 576000000, 583200000, 585937500, 589824000, 590490000, 597196800, 597871125, 600000000, 603979776, 604661760, 607500000, 612220032, 614400000, 615093750, 622080000, 625000000, 629145600, 629856000, 632812500, 637009920, 637729200, 640000000, 644972544, 645700815, 648000000, 655360000, 656100000, 663552000, 664301250, 671088640, 671846400, 675000000, 679477248, 680244480, 683437500, 688747536, 691200000, 699840000, 703125000, 707788800, 708588000, 716636160, 717445350, 720000000, 725594112, 729000000, 732421875, 737280000, 738112500, 746496000, 750000000, 754974720, 755827200, 759375000, 764411904, 765275040, 768000000, 774840978, 777600000, 781250000, 786432000, 787320000, 791015625, 796262400, 797161500, 800000000, 805306368, 806215680, 810000000, 816293376, 819200000, 820125000, 829440000, 838860800, 839808000, 843750000, 849346560, 850305600, 854296875, 859963392, 860934420, 864000000, 874800000, 878906250, 884736000, 885735000, 895795200, 900000000, 905969664, 906992640, 911250000, 918330048, 921600000, 922640625, 933120000, 937500000, 943718400, 944784000, 949218750, 955514880, 956593800, 960000000, 967458816, 972000000, 976562500, 983040000, 984150000, 995328000, 996451875, 1000000000, 1006632960, 1007769600, 1012500000, 1019215872, 1020366720, 1024000000, 1025156250, 1033121304, 1036800000, 1048576000, 1049760000, 1054687500, 1061683200, 1062882000, 1073741824, 1074954240, 1076168025, 1080000000, 1088391168, 1093500000, 1105920000, 1107168750, 1119744000, 1125000000, 1132462080, 1133740800, 1139062500, 1146617856, 1147912560, 1152000000, 1162261467, 1166400000, 1171875000, 1179648000, 1180980000, 1194393600, 1195742250, 1200000000, 1207959552, 1209323520, 1215000000, 1220703125, 1224440064, 1228800000, 1230187500, 1244160000, 1250000000, 1258291200, 1259712000, 1265625000, 1274019840, 1275458400, 1280000000, 1289945088, 1291401630, 1296000000, 1310720000, 1312200000, 1318359375, 1327104000, 1328602500, 1342177280, 1343692800, 1350000000, 1358954496, 1360488960, 1366875000, 1377495072, 1382400000, 1399680000, 1406250000, 1415577600, 1417176000, 1423828125, 1433272320, 1434890700, 1440000000, 1451188224, 1458000000, 1464843750, 1474560000, 1476225000, 1492992000, 1500000000, 1509949440, 1511654400, 1518750000, 1528823808, 1530550080, 1536000000, 1537734375, 1549681956, 1555200000, 1562500000, 1572864000, 1574640000, 1582031250, 1592524800, 1594323000, 1600000000, 1610612736, 1612431360, 1620000000, 1632586752, 1638400000, 1640250000, 1658880000, 1660753125, 1677721600, 1679616000, 1687500000, 1698693120, 1700611200, 1708593750, 1719926784, 1721868840, 1728000000, 1749600000, 1757812500, 1769472000, 1771470000, 1791590400, 1793613375, 1800000000, 1811939328, 1813985280, 1822500000, 1836660096, 1843200000, 1845281250, 1866240000, 1875000000, 1887436800, 1889568000, 1898437500, 1911029760, 1913187600, 1920000000, 1934917632, 1937102445, 1944000000, 1953125000, 1966080000, 1968300000, 1990656000, 1992903750, 2000000000, 2013265920, 2015539200, 2025000000, 2038431744, 2040733440, 2048000000, 2050312500, 2066242608, 2073600000, 2097152000, 2099520000, 2109375000, 2123366400 };
class Solution {
public:
int nthUglyNumber(int n) {
return ans[n-1];
}
};
劍指 Offer 50. 第一個只出現一次的字元
在字串 s 中找出第一個只出現一次的字元。如果沒有,返回一個單空格。 s 只包含小寫字母。
示例:
s = "abaccdeff"
返回 "b"
s = ""
返回 " "
限制:
0 <= s 的長度 <= 50000
class Solution {
public:
char firstUniqChar(string s) {
int loc[26];//初始值是-1,重複是-2,大於等於0是id
memset(loc,-1,4*26);
for(int i=0;i<s.length();i++)
{
int c=s[i]-'a';
if(loc[c]>=0)loc[c]=-2;
if(loc[c]==-1)loc[c]=i;
}
int ans=-1,m=s.length();
for(int i=0;i<26;i++)if(loc[i]>=0 && m>loc[i])m=loc[i],ans=i;
if(ans==-1)return ' ';
return ans+'a';
}
};
劍指 Offer 51. 陣列中的逆序對(離散化+sum型線段樹)
在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數。
示例 1:
輸入: [7,5,6,4]
輸出: 5
限制:
0 <= 陣列長度 <= 50000
#include <utility>
//拓展資料域,加上id
template<typename T>
vector<pair<T, int>>expand(vector<T>v)
{
vector<pair<T, int>>ans;
ans.resize(v.size());
for (int i = 0; i < v.size(); i++)ans[i].first = v[i], ans[i].second = i;
return ans;
}
//提取pair陣列的first
template<typename T1, typename T2>
vector<T1> fdraw(vector<pair<T1, T2>>v)
{
vector<T1>ans(v.size());
for (int i = 0; i < v.size(); i++)ans[i] = v[i].first;
return ans;
}
//提取pair陣列的second
template<typename T1, typename T2>
vector<T2> fdraw2(vector<pair<T1, T2>>v)
{
vector<T2>ans(v.size());
for (int i = 0; i < v.size(); i++)ans[i] = v[i].second;
return ans;
}
//給vector拓展,加上id並排序
template<typename T>
bool cmp(pair<T, int> x, pair<T, int> y)
{
if (x.first == y.first)return x.second < y.second;
return x.first < y.first;
}
template<typename T>
vector<pair<T, int>> sortWithId(vector<T>v)
{
vector<pair<T, int>>ans = expand(v);
sort(ans.begin(), ans.end(),cmp<T>);
return ans;
}
//排序後陣列中的每個數的原ID,輸入8 5 6 7,輸出1 2 3 0,也可以直接求逆置換
template<typename T>
vector<int> sortId(vector<T>v)
{
return fdraw2(sortWithId(v));
}
//每個數在排序後的陣列中的ID,輸入8 5 6 7,輸出3 0 1 2
template<typename T>
vector<int> sortId2(vector<T>v)
{
return sortId(sortId(v));
}
int num[100001], sum[400001];
const int p = 1000000007;
void update(int key, int low, int high, int uplace)
{
if (low == high)
{
sum[key] = num[low];
return;
}
int mid = (low + high) / 2;
if (uplace <= mid)update(key * 2, low, mid, uplace);
else update(key * 2 + 1, mid + 1, high, uplace);
sum[key] = (sum[key * 2] + sum[key * 2 + 1]) % p;
}
int query(int key, int low, int high, int x, int y)
{
if (low == x && high == y)return sum[key];
int mid = (low + high) / 2;
if (mid < x)return query(key * 2 + 1, mid + 1, high, x, y);
if (mid >= y)return query(key * 2, low, mid, x, y);
return (query(key * 2, low, mid, x, mid) + query(key * 2 + 1, mid + 1, high, mid + 1, y)) % p;
}
class Solution {
public:
int reversePairs(vector<int>& nums) {
memset(num, 0, sizeof(num));
memset(sum, 0, sizeof(sum));
vector<int>r = sortId2(nums);
int ans = 0, len = nums.size();
for (int i = 0; i < r.size(); i++)
{
ans += query(1, 1, len, r[i] + 1, len);
num[r[i] + 1] = 1;
update(1, 1, len, r[i] + 1);
}
return ans;
}
};
劍指 Offer 52. 兩個連結串列的第一個公共節點 160. 相交連結串列
輸入兩個連結串列,找出它們的第一個公共節點。
如下面的兩個連結串列:
在節點 c1 開始相交。
示例 1:
輸入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
輸出:Reference of the node with value = 8
輸入解釋:相交節點的值為 8 (注意,如果兩個列表相交則不能為 0)。從各自的表頭開始算起,連結串列 A 為 [4,1,8,4,5],連結串列 B 為 [5,0,1,8,4,5]。在 A 中,相交節點前有 2 個節點;在 B 中,相交節點前有 3 個節點。
示例2:
輸入:intersectVal= 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
輸出:Reference of the node with value = 2
輸入解釋:相交節點的值為 2 (注意,如果兩個列表相交則不能為 0)。從各自的表頭開始算起,連結串列 A 為 [0,9,1,2,4],連結串列 B 為 [3,2,4]。在 A 中,相交節點前有 3 個節點;在 B 中,相交節點前有 1 個節點。
示例3:
輸入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
輸出:null
輸入解釋:從各自的表頭開始算起,連結串列 A 為 [2,6,4],連結串列 B 為 [1,5]。由於這兩個連結串列不相交,所以 intersectVal 必須為 0,而 skipA 和 skipB 可以是任意值。
解釋:這兩個連結串列不相交,因此返回 null。
注意:
如果兩個連結串列沒有交點,返回 null.
在返回結果後,兩個連結串列仍須保持原有的結構。
可假定整個連結串列結構中沒有迴圈。
程式儘量滿足 O(n) 時間複雜度,且僅用 O(1) 記憶體。
//獲取連結串列長度
int GetLength(ListNode *p)
{
int ans=0;
while(p)
{
ans++;
p=p->next;
}
return ans;
}
class Solution {
public:
ListNode *getIntersectionNode2(ListNode *headA, ListNode *headB) {
if(headA==headB)return headA;
return getIntersectionNode2(headA->next,headB->next);
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int dl=GetLength(headA)-GetLength(headB);
while(dl>0)headA=headA->next,dl--;
while(dl<0)headB=headB->next,dl++;
return getIntersectionNode2(headA,headB);
}
};
劍指 Offer 53 - I. 在排序陣列中查詢數字 I 34. 在排序陣列中查詢元素的第一個和最後一個位置
統計一個數字在排序陣列中出現的次數。
示例 1:
輸入: nums = [5,7,7,8,8,10], target = 8
輸出: 2
示例2:
輸入: nums = [5,7,7,8,8,10], target = 6
輸出: 0
限制:
0 <= 陣列長度 <= 50000
程式碼:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
auto it1 = lower_bound(nums.begin(),nums.end(),target);
auto it2 = upper_bound(nums.begin(), nums.end(), target);
int res1, res2;
vector<int>ans;
if (it1 == it2)res1 = res2 = -1;
else res1 = it1 - nums.begin(), res2 = it2 - nums.begin()-1;
ans.insert(ans.end(), res1);
ans.insert(ans.end(), res2);
return ans;
}
int search(vector<int>& nums, int target) {
vector<int> ans = searchRange(nums,target);
return ans[1]-ans[0]+(ans[0]>-1);
}
};
劍指 Offer 53 - II. 0~n-1中缺失的數字
一個長度為n-1的遞增排序陣列中的所有數字都是唯一的,並且每個數字都在範圍0~n-1之內。在範圍0~n-1內的n個數字中有且只有一個數字不在該陣列中,請找出這個數字。
示例 1:
輸入: [0,1,3]
輸出: 2
示例2:
輸入: [0,1,2,3,4,5,6,7,9]
輸出: 8
限制:
1 <= 陣列長度 <= 10000
class Solution {
public:
int missingNumber(vector<int>& nums) {
int low=0,high=nums.size()-1,mid;
if(nums[high]==high)return high+1;
while(low<high-1)
{
mid=(low+high)/2;
if(nums[mid]==mid)low=mid;
else high=mid;
}
return (nums[low]==low)+low;
}
};
劍指 Offer 54. 二叉搜尋樹的第k大節點
給定一棵二叉搜尋樹,請找出其中第k大的節點。
示例 1:
輸入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
輸出: 4
示例 2:
輸入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
輸出: 4
限制:
1 ≤ k ≤ 二叉搜尋樹元素個數
簡單做法:
//求節點個數
int countNodes(TreeNode* root) {
if (!root)return 0;
return countNodes(root->left) + countNodes(root->right) + 1;
}
class Solution {
public:
int kthLargest(TreeNode* root, int k) {
int num = countNodes(root->right);
if(k<=num)return kthLargest(root->right,k);
if(k==num+1)return root->val;
return kthLargest(root->left,k-num-1);
}
};
時間複雜度:O(n^2)
其實可以優化一下,可以實現O(n)的時間複雜度
class Solution {
public:
int ans;
int kthLargest(TreeNode* root, int k) {
ans=0;
kthLargest2(root,k);
return ans;
}
int kthLargest2(TreeNode* root, int k) {
if (!root)return 0;
int num = kthLargest2(root->right,k);
if(ans)return 0;
if(k==num+1)
{
ans=root->val;
return 0;
}
return kthLargest2(root->left,k-num-1)+num+1;
}
};
劍指 Offer 55 - I. 二叉樹的深度 104. 二叉樹的最大深度
題目:
給定一個二叉樹,找出其最大深度。
二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。
說明:葉子節點是指沒有子節點的節點。
示例:
給定二叉樹 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度3 。
程式碼:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (!root)return 0;
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
劍指 Offer 55 - II. 平衡二叉樹 110. 平衡二叉樹
題目:
給定一個二叉樹,判斷它是否是高度平衡的二叉樹。
本題中,一棵高度平衡二叉樹定義為:
一個二叉樹每個節點的左右兩個子樹的高度差的絕對值不超過1。
示例 1:
給定二叉樹 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回 true 。
示例 2:
給定二叉樹 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回false 。
程式碼:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (!root)return 0;
int d1 = maxDepth(root->left), d2 = maxDepth(root->right);
if (d1<0 || d2<0 || d1 - d2 > 1 || d2 - d1 > 1)return -1;
return max(d1,d2) + 1;
}
bool isBalanced(TreeNode* root) {
return maxDepth(root) >= 0;
}
};
劍指 Offer 56 - I. 陣列中數字出現的次數(尋找僅出現一次的2個數)
一個整型陣列 nums 裡除兩個數字之外,其他數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)。
示例 1:
輸入:nums = [4,1,4,6]
輸出:[1,6] 或 [6,1]
示例 2:
輸入:nums = [1,2,10,4,1,4,3,3]
輸出:[2,10] 或 [10,2]
限制:
2 <= nums.length <= 10000
int func(int x)
{
return x;
}
int xorr;
int func2(int x)
{
return (x&xorr)?x:0;
}
int xorSum(vector<int>v,int(*f)(int))
{
int ans=0;
for(int i=0;i<v.size();i++)ans^=f(v[i]);
return ans;
}
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int xo=xorSum(nums,func);
xorr=xo&-xo;
vector<int>ans(2);
ans[0]=xorSum(nums,func2);
ans[1]=ans[0]^xo;
return ans;
}
};
劍指 Offer 56 - II. 陣列中數字出現的次數 II(三進位制異或)
在一個數組 nums 中除一個數字只出現一次之外,其他數字都出現了三次。請找出那個只出現一次的數字。
示例 1:
輸入:nums = [3,4,3,3]
輸出:4
示例 2:
輸入:nums = [9,1,7,9,7,9,7]
輸出:1
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
int func(int x)
{
return x;
}
long long xor3(long long a,long long b)//3進位制異或
{
if(a==0||b==0)return a+b;
return xor3(a/3,b/3)*3+(a%3+b%3)%3;
}
int xor3Sum(vector<int>v,int(*f)(int))
{
long long ans=0;
for(int i=0;i<v.size();i++)ans=xor3(ans,f(v[i]));
return ans;
}
class Solution {
public:
int singleNumber(vector<int>& nums) {
return xor3Sum(nums,func);
}
};
劍指 Offer 57. 和為s的兩個數字
輸入一個遞增排序的陣列和一個數字s,在陣列中查詢兩個數,使得它們的和正好是s。如果有多對數字的和等於s,則輸出任意一對即可。
示例 1:
輸入:nums = [2,7,11,15], target = 9
輸出:[2,7] 或者 [7,2]
示例 2:
輸入:nums = [10,26,30,31,47,60], target = 40
輸出:[10,30] 或者 [30,10]
限制:
1 <= nums.length <= 10^5
1 <= nums[i]<= 10^6
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int i=0,j=nums.size()-1;
vector<int>ans(2);
while(i<j)
{
if(nums[i]+nums[j]>target)j--;
if(nums[i]+nums[j]<target)i++;
if(nums[i]+nums[j]==target)
{
ans[0]=nums[i],ans[1]=nums[j];
return ans;
}
}
return ans;
}
};
劍指 Offer 57 - II. 和為s的連續正數序列
輸入一個正整數 target ,輸出所有和為 target 的連續正整數序列(至少含有兩個數)。
序列內的數字由小到大排列,不同序列按照首個數字從小到大排列。
示例 1:
輸入:target = 9
輸出:[[2,3,4],[4,5]]
示例 2:
輸入:target = 15
輸出:[[1,2,3,4,5],[4,5,6],[7,8]]
限制:
1 <= target <= 10^5
思路:
等差數列求和公式,因式分解
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
target*=2;
vector<vector<int>>ans;
for(int i=2;i*i<target;i++)
{
if(target%i)continue;
int j=target/i;
if((i+j)%2==0)continue;
vector<int>tmp(i);
for(int k=0;k<i;k++)tmp[k]=k+(j+1-i)/2;
ans.insert(ans.begin(),tmp);
}
return ans;
}
};
劍指 Offer 58 - I. 翻轉單詞順序 151. 翻轉字串裡的單詞
輸入一個英文句子,翻轉句子中單詞的順序,但單詞內字元的順序不變。為簡單起見,標點符號和普通字母一樣處理。例如輸入字串"I am a student. ",則輸出"student. a am I"。
示例 1:
輸入: "the sky is blue"
輸出:"blue is sky the"
示例 2:
輸入: " hello world! "
輸出:"world! hello"
解釋: 輸入字串可以在前面或者後面包含多餘的空格,但是反轉後的字元不能包括。
示例 3:
輸入: "a good example"
輸出:"example good a"
解釋: 如果兩個單詞間有多餘的空格,將反轉後單詞間的空格減少到只含一個。
說明:
無空格字元構成一個單詞。
輸入字串可以在前面或者後面包含多餘的空格,但是反轉後的字元不能包括。
如果兩個單詞間有多餘的空格,將反轉後單詞間的空格減少到只含一個。
//翻轉vector
template<typename T>
vector<T> frev(vector<T> &v)
{
vector<T> ans;
ans.resize(v.size());
for(int i=0;i<v.size();i++)ans[i]=v[v.size()-1-i];
return ans;
}
//把字串按照分隔符拆開成若干字串
vector<string> stringSplit(string text)
{
vector<string>v;
v.clear();
int low=0,key=0;
for(int i=0;i<=text.length();i++)
{
if(i==text.length() || text[i]==' ')//分隔符
{
if(i>low)v.insert(v.end(),text.substr(low,i-low));
low=i+1;
}
}
return v;
}
//把字串列表拼接起來,空格隔開
string stringJoin(vector<string>v)
{
if(v.size()==0)return "";
string ans=v[0];
for(int i=1;i<v.size();i++)ans+=" "+v[i];
return ans;
}
class Solution {
public:
string reverseWords(string s) {
vector<string>v=stringSplit(s);
return stringJoin(frev(v));
}
};
劍指 Offer 58 - II. 左旋轉字串
字串的左旋轉操作是把字串前面的若干個字元轉移到字串的尾部。請定義一個函式實現字串左旋轉操作的功能。比如,輸入字串"abcdefg"和數字2,該函式將返回左旋轉兩位得到的結果"cdefgab"。
示例 1:
輸入: s = "abcdefg", k = 2
輸出:"cdefgab"
示例 2:
輸入: s = "lrloseumgh", k = 6
輸出:"umghlrlose"
限制:
1 <= k < s.length <= 10000
class Solution {
public:
string reverseLeftWords(string s, int k) {
return s.substr(k,s.length()-k)+s.substr(0,k);
}
};
劍指 Offer 59 - I. 滑動視窗的最大值
題目:
給定一個數組 nums,有一個大小為k的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k個數字。滑動視窗每次只向右移動一位。
返回滑動視窗中的最大值。
進階:
你能線上性時間複雜度內解決此題嗎?
示例:
輸入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
輸出: [3,3,5,5,6,7]
解釋:
滑動視窗的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
提示:
1 <= nums.length <= 10^5
-10^4<= nums[i]<= 10^4
1 <= k<= nums.length
程式碼:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
while (--k>0)
{
for (int i = 0; i < nums.size() - 1; i++)nums[i] = max(nums[i], nums[i + 1]);
nums.erase(nums.end()-1);
}
return nums;
}
};
劍指 Offer 59 - II. 佇列的最大值
請定義一個佇列並實現函式 max_value 得到佇列裡的最大值,要求函式max_value、push_back 和 pop_front 的均攤時間複雜度都是O(1)。
若佇列為空,pop_front 和 max_value需要返回 -1
示例 1:
輸入:
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
輸出:[null,null,null,2,1,2]
示例 2:
輸入:
["MaxQueue","pop_front","max_value"]
[[],[],[]]
輸出:[null,-1,-1]
限制:
1 <= push_back,pop_front,max_value的總運算元<= 10000
1 <= value <= 10^5
template<typename T>
void finsert(vector<T>&v,int id,T x)
{
if(id<0||id>v.size())return;
if(id==v.size())v.push_back(x);
v[id]=x;
}
class MaxQueue {
public:
queue<int>q;
vector<int>v;
int vlen;
MaxQueue() {
vlen=0;
}
int max_value() {
if(q.empty())return -1;
return v[0];
}
void push_back(int value) {
q.push(value);
bool flag=true;
for(int i=vlen;flag && i>0;i--)
{
if(value<=v[i-1])
{
finsert(v,i,value);
vlen=i+1;
flag=false;
}
}
if(flag)
{
finsert(v,0,value);
vlen=1;
}
}
int pop_front() {
if(q.empty())return -1;
int ans=q.front();
q.pop();
if(v[0]==ans)
{
v.erase(v.begin());
vlen--;
}
return ans;
}
};
劍指 Offer 60. n個骰子的點數
把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,打印出s的所有可能的值出現的概率。
你需要用一個浮點數陣列返回答案,其中第 i 個元素代表這 n 個骰子所能擲出的點數集合中第 i 小的那個的概率。
示例 1:
輸入: 1
輸出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]
示例2:
輸入: 2
輸出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]
限制:
1 <= n <= 11
//2個vector的卷積
template<typename T>
vector<T> juanJi(vector<T>&v1,vector<T>&v2)
{
vector<T>ans(v1.size()+v2.size()-1);
for(int i=0;i<v1.size();i++)for(int j=0;j<v2.size();j++)ans[i+j]+=v1[i]*v2[j];
return ans;
}
class Solution {
public:
vector<double> twoSum(int n) {
vector<double>v(6);
for(int i=0;i<6;i++)v[i]=1.0/6;
vector<double>ans=v;
while(--n)ans=juanJi(ans,v);
return ans;
}
};
劍指 Offer 61. 撲克牌中的順子
從撲克牌中隨機抽5張牌,判斷是不是一個順子,即這5張牌是不是連續的。2~10為數字本身,A為1,J為11,Q為12,K為13,而大、小王為 0 ,可以看成任意數字。A 不能視為 14。
示例1:
輸入: [1,2,3,4,5]
輸出: True
示例2:
輸入: [0,0,1,2,5]
輸出: True
限制:
陣列長度為 5
陣列的數取值為 [0, 13] .
class Solution {
public:
bool isStraight(vector<int>& nums) {
sort(nums.begin(),nums.end());
for(int i=1;i<nums.size();i++)if(nums[i]==nums[i-1] && nums[i]>0)return false;
for(int i=0;i<nums.size();i++)
{
if(nums[i]==0)continue;
return nums[4]-nums[i]<5;
}
return true;//whatever
}
};
劍指 Offer 62. 圓圈中最後剩下的數字
https://blog.csdn.net/nameofcsdn/article/details/111147902
劍指 Offer 63. 股票的最大利潤 121. 買賣股票的最佳時機
題目:
給定一個數組,它的第i個元素是一支給定股票第i天的價格。
如果你最多隻允許完成一筆交易(即買入和賣出一支股票),設計一個演算法來計算你所能獲取的最大利潤。
注意你不能在買入股票前賣出股票。
示例 1:
輸入: [7,1,5,3,6,4]
輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。
注意利潤不能是 7-1 = 6, 因為賣出價格需要大於買入價格。
示例 2:
輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種情況下, 沒有交易完成, 所以最大利潤為 0。
程式碼:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty())return 0;
int tmp = prices[0], ans = 0;
for (int i = 1; i < prices.size(); i++)
{
ans = max(ans, prices[i] - tmp);
tmp = min(tmp, prices[i]);
}
return ans;
}
};
劍指 Offer 64. 求1+2+…+n
求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。
示例 1:
輸入: n = 3
輸出:6
示例 2:
輸入: n = 9
輸出:45
限制:
1 <= n<= 10000
class Solution {
public:
int sumNums(int n) {
n && (n=n+sumNums(n-1));
return n;
}
};
劍指 Offer 65. 不用加減乘除做加法
寫一個函式,求兩個整數之和,要求在函式體內不得使用 “+”、“-”、“*”、“/” 四則運算子號。
示例:
輸入: a = 1, b = 1
輸出: 2
提示:
a,b均可能是負數或 0
結果不會溢位 32 位整數
class Solution {
public:
int add(int a, int b) {
return b?add(a^b,unsigned(a&b)<<1):a;
}
};
劍指 Offer 66. 構建乘積陣列
給定一個數組 A[0,1,…,n-1],請構建一個數組 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
示例:
輸入: [1,2,3,4,5]
輸出: [120,60,40,30,24]
提示:
所有元素乘積之和不會溢位 32 位整數
a.length <= 100000
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
if (a.size() == 0)return a;
vector<int>b = a, ans = a;
for (int i = b.size() - 2; i >= 0; i--)b[i] *= b[i + 1];
a.insert(a.begin(), 1);
for (int i = 1; i <= b.size() - 2; i++)a[i + 1] *= a[i], ans[i] = a[i] * b[i + 1];
ans[0]=b[1], ans[b.size() - 1] = a[b.size() - 1];
return ans;
}
};
劍指 Offer 67. 把字串轉換成整數 8. 字串轉換整數 (atoi)
寫一個函式 StrToInt,實現把字串轉換成整數這個功能。不能使用 atoi 或者其他類似的庫函式。
首先,該函式會根據需要丟棄無用的開頭空格字元,直到尋找到第一個非空格的字元為止。
當我們尋找到的第一個非空字元為正或者負號時,則將該符號與之後面儘可能多的連續數字組合起來,作為該整數的正負號;假如第一個非空字元是數字,則直接將其與之後連續的數字字元組合起來,形成整數。
該字串除了有效的整數部分之後也可能會存在多餘的字元,這些字元可以被忽略,它們對於函式不應該造成影響。
注意:假如該字串中的第一個非空格字元不是一個有效整數字符、字串為空或字串僅包含空白字元時,則你的函式不需要進行轉換。
在任何情況下,若函式不能進行有效的轉換時,請返回 0。
說明:
假設我們的環境只能儲存 32 位大小的有符號整數,那麼其數值範圍為[−231,231− 1]。如果數值超過這個範圍,請返回 INT_MAX (231− 1) 或INT_MIN (−231) 。
示例1:
輸入: "42"
輸出: 42
示例2:
輸入: " -42"
輸出: -42
解釋: 第一個非空白字元為 '-', 它是一個負號。
我們儘可能將負號與後面所有連續出現的數字組合起來,最後得到 -42 。
示例3:
輸入: "4193 with words"
輸出: 4193
解釋: 轉換截止於數字 '3' ,因為它的下一個字元不為數字。
示例4:
輸入: "words and 987"
輸出: 0
解釋: 第一個非空字元是 'w', 但它不是數字或正、負號。
因此無法執行有效的轉換。
示例5:
輸入: "-91283472332"
輸出: -2147483648
解釋: 數字 "-91283472332" 超過 32 位有符號整數範圍。
因此返回 INT_MIN (−231) 。
class Solution {
public:
long long numstrToInt(string s) {
if (!s.length()) {
return 0;
}
if (s[0] == '0') {
return numstrToInt(s.substr(1, s.length() - 1));
}
long long ans = 0;
for (int i = 0; i < s.length() && i<11; i++) {
if (!isdigit(s[i])) {
break;
}
ans = ans * 10 + s[i] - '0';
}
return ans;
}
int lltoint(long long x) {
if (x < INT_MIN) {
return INT_MIN;
}
if (x > INT_MAX) {
return INT_MAX;
}
return int(x);
}
int strToInt(string str) {
if (!str.length()) {
return 0;
}
if (str[0] == ' ') {
return strToInt(str.substr(1, str.length() - 1));
}
if (str[0] == '+') {
return lltoint(numstrToInt(str.substr(1, str.length() - 1)));
}
if (str[0] == '-') {
return lltoint(-numstrToInt(str.substr(1, str.length() - 1)));
}
if (isdigit(str[0])) {
return lltoint(numstrToInt(str));
}
return 0;
}
};
劍指 Offer 68 - I. 235. 二叉搜尋樹的最近公共祖先
題目:
給定一個二叉搜尋樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義為:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”
例如,給定如下二叉搜尋樹:root =[6,2,8,0,4,7,9,null,null,3,5]
示例 1:
輸入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
輸出: 6
解釋: 節點 2 和節點 8 的最近公共祖先是 6。
示例 2:
輸入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
輸出: 2
解釋: 節點 2 和節點 4 的最近公共祖先是 2, 因為根據定義最近公共祖先節點可以為節點本身。
說明:
所有節點的值都是唯一的。
p、q 為不同節點且均存在於給定的二叉搜尋樹中。
程式碼:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (p->val > q->val){
TreeNode* tmp = p;
p = q, q = tmp;
}
if (root->val < p->val)return lowestCommonAncestor(root->right, p, q);
if (root->val > q->val)return lowestCommonAncestor(root->left, p, q);
return root;
}
};
劍指 Offer 68 - II. 236. 二叉樹的最近公共祖先
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義為:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”
例如,給定如下二叉樹:root =[3,5,1,6,2,0,8,null,null,7,4]
示例 1:
輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
輸出: 3
解釋: 節點 5 和節點 1 的最近公共祖先是節點 3。
示例2:
輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
輸出: 5
解釋: 節點 5 和節點 4 的最近公共祖先是節點 5。因為根據定義最近公共祖先節點可以為節點本身。
說明:
所有節點的值都是唯一的。
p、q 為不同節點且均存在於給定的二叉樹中。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || root == p || root == q) {
return root;
}
TreeNode* ret1 = lowestCommonAncestor(root->left, p, q);
TreeNode* ret2 = lowestCommonAncestor(root->right, p, q);
if (ret1 && ret2) {
return root;
}
return ret1?ret1:ret2;
}
};