力扣OJ 剑指 Offer(31-68)

目录

剑指 Offer 31. 栈的压入、弹出序列

剑指 Offer 33. 二叉搜索树的后序遍历序列

剑指 Offer 35. 复杂链表的复制

剑指 Offer 36. 二叉搜索树与双向链表

剑指 Offer 39. 数组中出现次数超过一半的数字

剑指 Offer 42. 连续子数组的最大和

剑指 Offer 45. 把数组排成最小的数(贪心)

剑指 Offer 48. 最长不含重复字符的子字符串

剑指 Offer 49. 丑数

剑指 Offer 50. 第一个只出现一次的字符

剑指 Offer 51. 数组中的逆序对(离散化+sum型线段树)

剑指 Offer 52. 两个链表的第一个公共节点

剑指 Offer 53 - I. 在排序数组中查找数字 I

剑指 Offer 53 - II. 0~n-1中缺失的数字

剑指 Offer 54. 二叉搜索树的第k大节点

剑指 Offer 55 - I. 二叉树的深度

剑指 Offer 55 - II. 平衡二叉树

剑指 Offer 56 - I. 数组中数字出现的次数(寻找仅出现一次的2个数)

剑指 Offer 56 - II. 数组中数字出现的次数 II(三进制异或)

剑指 Offer 57. 和为s的两个数字

剑指 Offer 57 - II. 和为s的连续正数序列

剑指 Offer 58 - I. 翻转单词顺序

剑指 Offer 58 - II. 左旋转字符串

剑指 Offer 59 - I. 滑动窗口的最大值

剑指 Offer 59 - II. 队列的最大值

剑指 Offer 60. n个骰子的点数

剑指 Offer 61. 扑克牌中的顺子

剑指 Offer 62. 圆圈中最后剩下的数字

剑指 Offer 63. 股票的最大利润

剑指 Offer 64. 求1+2+…+n

剑指 Offer 65. 不用加减乘除做加法

剑指 Offer 66. 构建乘积数组

剑指 Offer 67. 把字符串转换成整数

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

剑指 Offer 68 - II. 二叉树的最近公共祖先


剑指 Offer 31. 栈的压入、弹出序列

给定 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 35. 复杂链表的复制

题目:

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的 深拷贝。 

我们用一个由 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. 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 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. 连续子数组的最大和

题目:

给定一个整数数组 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. 最长不含重复字符的子字符串

题目:

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 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. 丑数

题目:

编写一个程序,找出第 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. 两个链表的第一个公共节点

输入两个链表,找出它们的第一个公共节点。

如下面的两个链表:

在节点 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

二分、三分 https://blog.csdn.net/nameofcsdn/article/details/111825915

剑指 Offer 53 - II. 0~n-1中缺失的数字

二分、三分 https://blog.csdn.net/nameofcsdn/article/details/111825915

剑指 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. 二叉树的深度

题目:

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [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. 平衡二叉树 https://blog.csdn.net/nameofcsdn/article/details/114372257

剑指 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. 翻转单词顺序

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"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. 股票的最大利润

题目:

给定一个数组,它的第 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. 把字符串转换成整数

写一个函数 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. 二叉搜索树的最近公共祖先

题目:

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 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. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 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;
      }
 };

猜你喜欢

转载自blog.csdn.net/nameofcsdn/article/details/113280987