string类函数和牛客网剑指offer刷题记录

1.strcat

char* strcat(char *strDest,const char *strSrc){
    assert(strDest && strSrc);
    char *p = strDest;
    while(*p){
        p++;//找到*p == '\0'
    }
    while(*p++ = *strSrc++);//直到*p值为'\0'时结束
    return strDest;
}

2.strlen

int strlen(const char *str){
    assert(str);
    int len = 0;
    while(*str++)//找到str为'\0'
        len++;
    return len;
}
int strlen(const char *str){
    assert(str);
    return (*str == 0) ? 0 : 1 + strlen(str + 1);//找到str为'\0'
}

3.strcmp

int strcmp(const char *str1, const char *str2){
    assert(str1 && str2);
    while((*str1 == *str2) && *str1){
        str1++;
        str2++;
    }
    if(*str1 == *str2){//循环完 如果相等  即都为'\0'
        return 0;
    }
    return *(unsigned char*)str1 > *(unsigned char*)str2 ? 1 : -1;
}

4,strcpy

char* strcpy(char *strDest, const char *strSrc){
    assert(strDest && strSrc);
    char *p = strDest;
    while(*p++ = *strSrc++);
    return strDest;
}

5.strstr

const char * strstr(const char * str, const char * substr){
    assert(substr && str);
    const char * psub = substr;
    const char * pstr = str;
    while(*pstr){
        const char * tmp = pstr;
        while(*tmp++ == *psub++)//str中找到一个和psub头相同的  往下比较
            ;
        if(*psub == '\0')//比较完   substr结束 说明是子串  返回位置
            return pstr;
        psub = substr;
        pstr++;
    }
    return NULL;
}

6.memcpy

void* memcpy(void *dst, const void *src, size_t size){
    if(des == NULL || src == NULL){
        return NULL;
    }
    char *pdst = (char*)dst;
    char *psrc = (char*)src;
    if(pdst > psrc && pdst < psrc + size){//当两条字符串有重复时
        pdst = pdst + size - 1;
        psrc = psrc + size - 1;
        while(size--){
            *pdst-- == *psrc--;
        }
    }
    else{
        while(size--){
            *pdst++ = *psrc++;
        }
    }
    return dst;
}

1.斐波那契数列_

f[i] = f[i - 1] + f[i - 2]

class Solution {
public:
	int Fibonacci(int n) {
		vector<int> f(40, 0);
		f[0] = 0;
		f[1] = 1;
		for (int i = 2; i <= n; i++) {
			f[i] = f[i - 1] + f[i - 2];
		}
		return f[n];
	}
};

2.跳台阶_

f[i] = f[i - 1] + f[i - 2]

class Solution {
public:
	int jumpFloor(int number) {
		if (number <= 0) {
			return -1;
		}

		vector<int> f(number, 0);

		if (number == 1 || number == 2) {
			return number;
		}
		f[0] = 1;
		f[1] = 2;
		for (int i = 2; i < number; i++) {
			f[i] = f[i - 1] + f[i - 2];
		}
		return f[number - 1];
	}
};

3.跳台阶扩展问题_

f[i] = f[i - 1] + f[i - 2]

class Solution {
public:
	int jumpFloorII(int number) {
		return 1 << number - 1;
	}
};

4.矩形覆盖_

f[i] = f[i - 1] + f[i - 2]

class Solution {
public:
	int rectCover(int number) {
		if (number == 0 || number == 1) {
			return number;
		}
		if (number < 0) { return -1; }
		vector<int> f(number+1, 0);
		f[0] = 1;
		f[1] = 1;
		for (int i = 2; i <= number; ++i) {
			f[i] = f[i - 1] + f[i - 2];
		}
		return f[number];
	}
};

5.二进制中1的个数_

val:1101000,val-1:1100111那么val&(val-1): 1100000

class Solution {
public:
	int  NumberOf1(int n) {
		int count = 0;
		while (n) {
			n = n & (n - 1);
            //例:val:1101000,val-1:1100111那么val&(val-1): 1100000
			count++;
		}
		return count;
	}
};

6.数值的整数次方_

1.指数大于0:for循环 *=

2.指数小于0:指数置反(前面加﹣),for循环 *=,结果取倒数(b=1/b)

class Solution {
public:
	double Power(double base, int exponent) {
		if (base == 0) { return 0; }
		if (exponent == 0) { return 1; }
		double b = 1;
		if (exponent > 0) {
			for (int i = 0; i < exponent; ++i) {
				b *= base;
			}
		}
		if (exponent < 0) {
			for (int i = 0; i < -exponent; ++i) {
				b *= base;
			}
			b = 1 / b;
		}
		return b;
	}
};

7.调整数组顺序使奇数位于偶数前面_

1.建两个vector分别存储奇 ,偶。最后拼接

2.建一个vector通过两个for循环下标自增插入

3.建两个vector分别存储奇 ,偶。最后使用范围insert插入

class Solution {
public:
	/**
	 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
	 *
	 *
	 * @param array int整型vector
	 * @return int整型vector
	 */
	vector<int> reOrderArray(vector<int>& array) {
		// write code here
		int ocount = 0;//奇数计数
		int ecount = 0;//偶数计数
		vector<int> oarray(array.size());
		vector<int> earray(array.size());
		for (int i = 0; i < array.size(); ++i) {
			if (array[i] % 2) {
				oarray[ocount] = array[i];
				ocount++;
			}
			else {
				earray[ecount] = array[i];
				ecount++;
			}
		}
		for (int i = 0; i < array.size(); ++i) {
			if (i < ocount) {
				array[i] = oarray[i];
			}
			if (i < ecount) {
				array[ocount + i] = earray[i];
			}
		}
		return array;
	}
};

class Solution {
public:
	/**
	 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
	 *
	 *
	 * @param array int整型vector
	 * @return int整型vector
	 */
	vector<int> reOrderArray(vector<int>& array) {
		// write code here
		int count = 0;//计数
		vector<int> arrays(array.size());
		for (int i = 0; i < array.size(); ++i) {
			if (array[i] % 2) {
				arrays[count++] = array[i];
			}
		}
		for (int i = 0; i < array.size(); ++i) {
			if (!(array[i] % 2)) {
				arrays[count++] = array[i];
			}
		}
		return arrays;
	}
};

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
    vector<int> reOrderArray(vector<int>& array) {
        // write code here
        vector<int> arrays1;
        vector<int> arrays2;
        int count = array.size();
        for(int i = 0; i < count; ++i){
            if(array[i]&1){
                arrays1.push_back(array[i]);
            }
            else{
                arrays2.push_back(array[i]);
            }
        }
        array.erase(array.begin(), array.end());
        array.insert(array.end(),arrays1.begin(),arrays1.end());
        array.insert(array.end(),arrays2.begin(),arrays2.end());
        return array;
    }
};

8.链表中倒数最后k个结点_//快慢链表

新建两个指针,一个指针先走k(p=p->next),走完k后和另外一个一起走直到结束,另外一个指针所在就是结果

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
	ListNode* FindKthToTail(ListNode* pHead, int k) {
		// write code here
		if (!pHead) { return nullptr; }
		ListNode* p = pHead;
		ListNode* q = pHead;
		while (--k) {
			if (p->next) {
				p = p->next;
			}
			else { return nullptr; }
		}
		while (p->next) {
			q = q->next;
			p = p->next;
		}
		return q;
	}
};

9.反转链表_

思路:不断地交换头节点下一个结点与标记结点后面的结点的位置,直到链表末尾,交换完成。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
	ListNode* ReverseList(ListNode* pHead) {
		if (pHead == nullptr) { return nullptr; }
		ListNode* p = nullptr;
		ListNode* q = nullptr;
		while (pHead != nullptr) {
			p = pHead->next;
			pHead->next = q;
			q = pHead;
			pHead = p;
		}
		return q;
	}
};

10.合并两个排序的链表_

链表1的当前节点的val小于链表2当前节点的val,就往链表1当前节点的下一个节点递归,否则往链表2当前节点的下一个节点递归。

直到某链表a到达末尾,返回另表b的头节点

/*struct ListNode {	
	int val;	
	struct ListNode *next;	
	ListNode(int x) :			
		val(x), 
		next(NULL) {	}};
*/ 
class Solution
{
public:
    ListNode *Merge(ListNode *pHead1, ListNode *pHead2)
    {
        if (pHead1 == nullptr)
        {
            return pHead2;
        }
        if (pHead2 == nullptr)
        {
            return pHead1;
        }
        if (pHead1->val < pHead2->val)
        {
            pHead1->next = Merge(pHead1->next, pHead2);
            return pHead1;
        }
        else
        {
            pHead2->next = Merge(pHead1, pHead2->next);
            return pHead2;
        }
    }
};

11.树的子结构_

根的值相等:递归判定子树,

根的值不等:分别递归左右子树,若其中一个找到和子树根值相等的节点,递归判定子树

判定子树递归直到出现节点的值与子树对应节点的值不等 返回false,

或者子树递归结束返回true

class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pSubRoot2)
    {
        bool result = false;
        if(pRoot1  && pSubRoot2 )
        {
            if(pRoot1->val == pSubRoot2->val) //根一致,递归子树
                result = isSubtree(pRoot1, pSubRoot2); 

            if(!result) //根不同,递归左子树
                result = HasSubtree(pRoot1->left, pSubRoot2);
            
            if(!result) //左子树不同,递归右子树
                result = HasSubtree(pRoot1->right, pSubRoot2);
        }
        return result;
    }
    
    bool isSubtree(TreeNode* pRoot1, TreeNode* pSubRoot2)
    {
        if(pSubRoot2 == nullptr) //若匹配到的子树nullptr
            return true;
        
        if(pRoot1 == nullptr)
            return false;

        if(pRoot1->val != pSubRoot2->val)
            return false;

        return isSubtree(pRoot1->left, pSubRoot2->left)
            && isSubtree(pRoot1->right, pSubRoot2->right);
    }
};

12.二叉树的镜像_

新建一个节点p存储节点指向left

节点指向left递归节点指向right

节点指向right递归节点指向left

结果返回当前节点

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
	TreeNode* Mirror(TreeNode* pRoot) {
		// write code here
		if (pRoot == nullptr) {
			return nullptr;
		} 
		TreeNode* p = pRoot->left;
		pRoot->left = Mirror(pRoot->right);
		pRoot->right = Mirror(p);
		return pRoot;
	}
};

13.顺时针打印矩阵_

定义四个方向

循环推入vector直到up>down或left>right(每次循环–right; --down; ++left; ++up;)

其中right向left,down向up要判定不在同一行或同一列

class Solution {
public:
	vector<int> printMatrix(vector<vector<int> > matrix) {
		vector<int> output;
		if (matrix.empty() || matrix[0].empty()) {
			return output;
		}
		int up = 0;
		int down = matrix.size() - 1;//列
		int left = 0;
		int right = matrix[0].size() - 1;//行
		output.reserve((down + 1) * (right + 1));
		while (up <= down && left <= right) {
			for (int i = left; i <= right; ++i) {
				output.push_back(matrix[up][i]);
			}
			for (int i = up + 1; i <= down; ++i) {
				output.push_back(matrix[i][right]);
			}
			if (up != down) {
				for (int i = right - 1; i >= left; --i) {
					output.push_back(matrix[down][i]);
				}
			}
			if (left != right) {
				for (int i = down - 1; i > up; --i) {
					output.push_back(matrix[i][left]);
				}
			}
			--right; --down; ++left; ++up;
		}
		return output;
	}
};

14.包含min函数的栈_

新建两个栈

其中一个栈用于保存推入的值,另一个保存推入值与其栈顶值的较小值(min)

class Solution {
public:
    void push(int value) {
        stackVal.push(value);    //每次stackVal都push value
        int minValue = value;
        if(!stackMin.empty()){
			minValue = std::min(stackMin.top(),value);//存真实更小
        }
        stackMin.push(minValue);//stackMin和stackVal大小一样
    }
    void pop() {
        if(!stackVal.empty()){
            stackVal.pop();//弹出后还是stackMin
            stackMin.pop();
        }
    }
    int top() {
        return stackVal.top();
    }
    int min() {
        return stackMin.top();
    }
private:
    stack<int> stackVal;
    stack<int> stackMin;
};

15.栈的压入、弹出序列_

新建一个栈,将vector1while循环压入栈,

循环内再使用一个while循环判定vector2的值(该值下标要小于栈的当前size)是否=栈顶值,等于就pop

最后返回栈是否为空

class Solution {
public:
	bool IsPopOrder(vector<int> pushV, vector<int> popV) {
		stack<int> s;
		int size = pushV.size();
		int i = 0;
		int j = 0;
		while (i < size) {
			s.push(pushV[i++]);
			while (!s.empty() && popV[j] == s.top() && j++ < popV.size()) {//判空   与栈顶相等   下标范围
				s.pop();
			}
		}
		return s.empty();
	}
};

16.从上往下打印二叉树_

新建队列q,vector,压入树当前根,

循环每次将队头的val压入vector,并将队头释放,root有子树压入子树

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
	vector<int> PrintFromTopToBottom(TreeNode* root) {
		vector<int> result;
		if (!root) { return result; }
		queue<TreeNode*> q;
		q.push(root);
		while (q.size()) {
			auto t = q.front();
			q.pop();//从对头删除
			result.push_back(t->val);
			if (t->left) {
				q.push(t->left);//从队尾插入
			}
			if (t->right) {
				q.push(t->right);
			}
		}
		return result;
	}
};

17.二叉搜索树的后序遍历序列_(左<根<右)

先统计seq中小于根的值的个数n,将这些归为左子树,其他归为右子树,

如果右子树存在小于根的值,返回false

否则将n-1作为左子树的根递归左子树

将n+1作为右子树最左边节点递归右子树

class Solution {//后序左右根
public:
	bool VerifySquenceOfBST(vector<int> sequence) {
		if (sequence.empty()) {
			return false;
		}
		stack<int> roots;
		roots.push(INT_MIN);
		int max = INT_MAX;
		for (int i = sequence.size() - 1; i > -1; --i) {
			if (sequence[i] > max) {
				return false;
			}
			while (sequence[i] < roots.top()) {
				max = roots.top();
				roots.pop();
			}
			roots.push(sequence[i]);
		}
		return true;
	}
};

class Solution {
public:
	bool VerifySquenceOfBST(vector<int> sequence) {
		if (sequence.empty()) {
			return false;
		}
		return VerifySquenceOfBST(sequence, 0, sequence.size() - 1);
	}
	bool VerifySquenceOfBST(vector<int> sequence, int begin, int end) {
		if (begin >= end) {
			return true;
		}
		int root = sequence[end];
		int splitPos = begin;
		while (splitPos < end && sequence[splitPos] < root) {
			splitPos++;//数左子树个数得到右子树个数
		}
		for (int i = splitPos; i < end; ++i) {
			if (sequence[i] < root) {
				return false;//右子树找大于根 返回false
			}
		}
		return VerifySquenceOfBST(sequence, begin, splitPos - 1)//左子树
			&& VerifySquenceOfBST(sequence, begin + splitPos, end - 1);//右子树
	}
};

18.二叉树中和为某一值的路径_

新建一个vector1,一个存储vector1的vector2

将当前节点的值压入vector,

如果该值与和相等,且当前节点无左右子树,将vector1压入vector2.

和 -= 改值,分别往左右子树递归。 直到节点不存在。

如果vector1非空 需要将最后压入值pop(退回到节点的根)

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
	vector<vector<int> > result;
	vector<int> tmp;
	vector<vector<int> > FindPath(TreeNode* root, int expectNumber) {
		if (root == nullptr || expectNumber == 0) {
			return result;
		}
		FindPaths(root, expectNumber);
		return result;
	}
	void FindPaths(TreeNode* root, int expectNumber) {
		if (root = nullptr) {
			return;
		}
		tmp.push_back(root->val);
		if (expectNumber == root->val
			&& root->left == nullptr
			&& root->right == nullptr) {
			result.push_back(tmp);
		}
		expectNumber -= root->val;
		FindPaths(root->left, expectNumber);
		FindPaths(root->right, expectNumber);

		if (!tmp.empty()) {
			tmp.pop_back();
		}
	}
};

19.复杂链表的复制_

//将副本链入原链表 A->a->B->b

//将副本随机节点指向原节点随机节点的副本
//A->a->B->b->C->c
//A->C a->c

/*
struct RandomListNode {
	int label;
	struct RandomListNode *next, *random;
	RandomListNode(int x) :
			label(x), next(NULL), random(NULL) {
	}
};
*/
class Solution {
public:
	RandomListNode* Clone(RandomListNode* pHead) {
		auto curNode = pHead;
		while (curNode) {
			RandomListNode* newNode = new RandomListNode(curNode->label);
			newNode->next = curNode->next;
			curNode->next = newNode;
			curNode = newNode->next;
		}//将副本链入原链表   A->a->B->b   
		curNode = pHead;
		while (curNode) {
			if (curNode->random) {
				curNode->next->random = curNode->random->next;
			}
			curNode = curNode->next->next;//跳到下两个节点   跳过副本节点
		}//将副本随机节点指向原节点随机节点的副本
		//A->a->B->b->C->c   
		//A->C   a->c

		auto pCloneHead = new RandomListNode(-1);
		auto cloneNode = pCloneHead;
		curNode = pHead;
		while (curNode) {
			cloneNode->next = curNode->next;//克隆指向A的副本//克隆->a
			cloneNode = cloneNode->next;//克隆的下一个
			curNode->next = curNode->next->next;//将A->a->B 变为A->B
			curNode = curNode->next;//A的下一个B
		}
		return pCloneHead->next;//返回(-1)节点
	}
};

20.二叉搜索树与双向链表_

先一直->left递归找到最左子树,然后其->left第一次为空,然后为last

last->right为当前节点,last赋为当前节点,以当前节点->right和last递归

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
	TreeNode* Convert(TreeNode* pRootOfTree) {
		if (pRootOfTree == nullptr) {
			return nullptr;
		}
		TreeNode* node = nullptr;
		Converts(pRootOfTree, node);
		while (node && node->left) {
			node = node->left;
		}
		return node;
	}
	void Converts(TreeNode* curNode, TreeNode*& lastNodeInList) {
		if (curNode == nullptr) {
			return;
		}·
		if (curNode->left) {
			Converts(curNode->left, lastNodeInList);//找左子树最小值
		}//当前节点左子树最小节点的左边为nullptr
		curNode->left = lastNodeInList;//当前节点左边为上一个节点
		if (lastNodeInList) {
			lastNodeInList->right = curNode;//上一个节点的右边为当前节点
		}
		lastNodeInList = curNode;//上一节点为当前节点
		if (curNode->right) {
			Converts(curNode->right, lastNodeInList);//找右子树
		}
	}
};

21.字符串的排列_

从str[0]开始,循环交换str[i],str[j](如果字母相等,跳过),下标每次+1递归,然后再次交换进行回溯

class Solution
{
public:
	vector<string> result;
	vector<string> Permutation(string str)
	{
		int length = str.length();
		if (length == 0 || length > 9)
		{
			return result;
		}
		Permutation(0, length, str);
		sort(result.begin(), result.end());
		return result;
	}
	void Permutation(int i, int length, string str)
	{
		if (i == length)
		{
			result.push_back(str);
		}
		else
		{
			for (int j = i; j < length; ++j)
			{
				if (j != i && str[j] == str[i])//重复字母 跳过
					continue;
				swap(str[i], str[j]);
				Permutation(i + 1, length, str);
				swap(str[i], str[j]);//回溯
			}
		}
	}
};

22.数组中出现次数超过一半的数字_

先进行一次sort排序,假设数组中有出现次数超过一半的数字,

那么这个数组的中间那个数字就一定是那个数,将他下标加一往后循环找,直到 numbers[i] < numbers[i+1]的位置,

然后从这个数下标递减找到numbers[i-1] < numbers[i]的位置并计数,

如果计数大于numbers大小的一半,返回这个数字,否则返回NULL

class Solution
{
public:
	int MoreThanHalfNum_Solution(vector<int> numbers)
	{
		int size = numbers.size();
		if (size < 1 || size > 50000)
		{
			return NULL;
		}
		if (size == 1)
		{
			return numbers[0];
		}
		sort(numbers.begin(), numbers.end());
		int num = size / 2;
		int count = 0;
		for (int i = 0; i < size; ++i)
		{
			if (numbers[i] == numbers[num])
			{
				count++;
			}
		}
		if (count > (size / 2))
		{
			return numbers[num];
		}
		return NULL;
	}
};

23.最小的K个数_

建一个multilist,set,

for循环,如果set的size<k,将值压入set,

否则(已经压入k个值)将val与set头比较,如果val<set.top(),

将头释放,压入val,

最后循环set,将val压入vector,返回vector

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> output;
        if(input.empty() || k <=0 || k > input.size()){
            return output;
        }
        sort(input.begin(), input.end());
        return vector<int>({input.begin(),input.begin()+k});
    }
};

class Solution
{
public:
	vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
	{
		vector<int> res;
		int size = input.size();
		if (size == 0 || k > size)
			return res;

		multiset<int, greater<int>> set; //带排序的set,大的在前面
		for (int val : input)
		{
			if (set.size() < k)
			{
				set.insert(val);
			}
			else
			{ //已经有k个元素的set
				if (val < *(set.begin()))
				{
					set.erase(set.begin());
					set.insert(val);
				}
			}
		}

		for (int val : set)
			res.push_back(val);

		return res;
	}
};

24.连续子数组的最大和_

建int类型的result,sum,result初始值为int类型最小值,sum为0;

for循环sum+=array的值,每次result = max(sum,result),如果sum<0,将sum置为0.

最后返回result

class Solution
{
public:
	int FindGreatestSumOfSubArray(vector<int> array)
	{
		if (array.empty())
		{
			return NULL;
		}
		int result = INT_MIN;
		int sum = 0;
		for (auto a : array)
		{
			if (sum < 0)//每次累加直到为0
			{
				sum = 0;
			}
			sum += a;
			result = max(sum, result);//取最大值
		}
		return result;
	}
};

25整数中1出现的次数(从1到n整数中1出现的次数)_

for循环设置num = i,

while循环条件为num存在,每次循环判断num % 10 == 1,成立计数加一。

每次循环num /= 10

返回sum

class Solution
{
public:
	int NumberOf1Between1AndN_Solution(int n)
	{
		if (n <= 0)
		{
			return 0;
		}
		if (n == 1)
		{
			return 1;
		}
		int sum = 0;
		for (int i = 1; i <= n; ++i)
		{
			int num = i;
			while (num)
			{
				if (num % 10 == 1)//对10取余求最后一位
				{
					++sum;
				}
				num /= 10;//往前递增一位
			}
		}
		return sum;
	}
};

26.把数组排成最小的数_

建立静态成员函数cmp(比较规则),

将numbers用sort排序,规则为cmp

for循环拼接排序后的numbers

返回拼接后的字符串

class Solution
{
public:
	static bool cmp(int a, int b)
	{
		string as = to_string(a);
		string bs = to_string(b);
		return as + bs < bs + as;
	}
	string PrintMinNumber(vector<int> numbers)
	{
		sort(numbers.begin(), numbers.end(), cmp);
		string res;
		for (auto x : numbers)
		{
			res += to_string(x);
		}
		return res;
	}
};

27.丑数_

如果数组中存在排序的丑数,那么下一个数是他们中其乘2、乘3、乘5中的最小值,

设置3个下标从0开始,

循环取这三个下标对应丑数分别乘以2,3,5的最小值,压入vector

取的是乘以哪个数的值就哪个下标+1,

class Solution {
public:
    /* 两种方法:
     * 第一种:直观暴力法, 如果一个数能被2整除,那么连续除2,如果能被3整除,那么连续除3,
     * 如果能被5整除,那么连续除5,最后结果为1,那么是丑数
     * 第二种:避免对非丑数的计算,以空间换时间的思想提高算法效率,如果数组中存在排序的丑数,那么
     * 下一个数他们中其乘2、乘3、乘5中的最小值
     */
    int GetUglyNumber_Solution(int index) {
        vector<int> vec;
        vec.push_back(1);
        
        int index2 = 0;
        int index3 = 0;
        int index5 = 0;
        
        for(int i = 1; i < index; ++i)
        {
            int val = min(min(vec[index2] * 2, vec[index3] * 3), vec[index5] * 5);
            vec.push_back(val);
            
            /* 不能使用else if,有可能出现最小值相同的情况  3*2  2*3 */
            if(val == vec[index2] * 2) ++index2;
            if(val == vec[index3] * 3) ++index3;
            if(val == vec[index5] * 5) ++index5;
        }
        
        return vec[index - 1];
    }
    
};

28.第一个只出现一次的字符_

建立unordered_map mp,for循环压入mp(++mp[ch]),

for循环第一个mp等于1的字符

class Solution
{
public:
	int FirstNotRepeatingChar(string str)
	{
		if (str.empty())
		{
			return -1;
		}
		unordered_map<char, int> mp;
		for (const char ch : str)
		{
			++mp[ch];
		}
		for (int i = 0; i < str.length(); ++i)
		{
			if (mp[str[i]] == 1)
				return i;
		}
		return -1;
	}
};

29.数组中的逆序对_

设置归并排序的两个头和尾,

然后进行归并排序循环,当归并时左边的值大于右边的值时,将左边尾下标 - 左边当前值的下标 + 1的值加入count计数,

如果count大于1000000007,就将count对1000000007取模得值设为count,

最后再次取模,返回

class Solution
{
public:
	int count = 0;
	void Msort(vector<int> &vec, int gap)
	{
		int len = vec.size();
		vector<int> tmp(len);
		int start1 = 0;
		int end1 = gap - 1;
		int start2 = gap;
		int end2 = min(start2 + gap - 1, len - 1);
		int i = 0;
		while (start2 < len)
		{
			while (start1 <= end1 && start2 <= end2)
			{
				if (vec[start1] > vec[start2])
				{
					tmp[i++] = vec[start2++];
					count += end1 - start1 + 1;
					if (count >= 1000000007)
					{
						count %= 1000000007;
					}
				}
				else
				{
					tmp[i++] = vec[start1++];
				}
			}
			while (start1 <= end1)//归并后左边有多余
			{
				tmp[i++] = vec[start1++];
			}
			while (start2 <= end2)//归并后右边有多余
			{
				tmp[i++] = vec[start2++];
			}
			start1 = end2 + 1;
			end1 = start1 + gap - 1;
			start2 = end1 + 1;
			end2 = min(start2 + gap - 1, len - 1);
		}
		
		while (start1 < len)//归并排序后如果有多出来的一个部分
		{
			tmp[i++] = vec[start1++];
		}
		for (int j = 0; j < len; j++)
		{
			vec[j] = tmp[j];
		}
	}
	int InversePairs(vector<int> data)
	{
		int len = data.size();
		if (len == 0)
		{
			return -1;
		}
		for (int gap = 1; gap < len; gap *= 2)
		{
			Msort(data, gap);
		}
		return count % 1000000007;
	}
};

30.两个链表的第一个公共结点_

在两个链表的尾部部拼接对方链表,然后while循环开始往下走,直到节点相同

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution
{
public:
	ListNode *FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)
	{
		auto p = pHead1, q = pHead2;
		while (p != q)
		{
			if (p)
			{
				p = p->next;
			}
			else
			{
				p = pHead2;
			}
			if (q)
			{
				q = q->next;
			}
			else
			{
				q = pHead1;
			}
		}
		return p;
	}
};

31.数字在升序数组中出现的次数_

使用二分查找找到这个数,然后下标往后找到第一个大于它的值,

在下标往前循化并计数,直到找到第一个小于它的值

返回计数

class Solution {
public:
    /* 二分查找 */
    int GetNumberOfK(vector<int> data ,int k) {
        int size = data.size();
        if(size == 0)
            return 0;
        int left = 0;
        int right = size - 1;
        int count = 0;
        while(left <= right)
        {
            int mid = (left + right) >> 1;
            if(data[mid] > k)
                right = mid - 1;
            else if(data[mid] < k)
                left = mid + 1;
            else{
                while(data[mid - 1] == data[mid])
                    --mid;
                
                while(data[mid++] == k)
                {
                    ++count;
                }
                break;
            }
        }
        return count;
        
    }
};

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int count = 0;
        int size = data.size();
        for(int i = 0; i < size; ++i){
            if(data[i] == k){
                count++;
            }
        }
        return count;
    }
};

32.二叉树的深度_

定义int类型left为函数向左递归,right为向右递归,

函数返回max(left,right)+1

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution//左右递归
{
public:
	int TreeDepth(TreeNode *pRoot)
	{
		if (!pRoot)
		{
			return 0;
		}
		int left = TreeDepth(pRoot->left);
		int right = TreeDepth(pRoot->right);
		return max(left, right) + 1;
	}
};

33.平衡二叉树_

如果节点不存在,返回0

定义int类型left为函数向左递归,判断left = -1,返回-1

right为向右递归,判断right = -1,返回-1

判断left-right的绝对值>1,返回-1

函数最后返回max(left,right)+1

class Solution
{
public:
	bool IsBalanced_Solution(TreeNode *pRoot)
	{
		return TreeDepth(pRoot) != -1;
	}
	int TreeDepth(TreeNode *pRoot)
	{
		if (!pRoot)
			return 0;
		int left = TreeDepth(pRoot->left);
		if (left == -1)
			return -1;
		int right = TreeDepth(pRoot->right);
		if (right == -1)
			return -1;
		if ((abs(left - right)) > 1)
		{
			return -1;
		}
		return max(left, right) + 1;
	}
};

34.数组中只出现一次的两个数字_

建立unordered_map mp,for循环压入mp(++mp[val]),

for循环将mp等于1的字符压入vector,返回vector

class Solution
{
public:
	/**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
	vector<int> FindNumsAppearOnce(vector<int> &array)
	{
		// write code here
		vector<int> result;
		unordered_map<int, int> mp;
		if (array.size() <= 2)
		{
			return array;
		}
		for (auto val : array)
		{
			++mp[val];
		}
		for (int i = 0; i < array.size(); ++i)
		{
			if (mp[array[i]] == 1)
			{
				result.push_back(array[i]);
			}
		}
		return result;
	}
};

35.和为S的连续正数序列_

for循环设j=i,

while循环(num<和),将j的值压入vector tmp,num叠加j++,

当num = 和时将tmp压入vector result,

清空tmp,num置为0

class Solution
{
public:
	vector<vector<int>> FindContinuousSequence(int sum)
	{
		int mid = sum / 2;
		int num = 0;
		vector<int> tmp;
		int j = 0;
		vector<vector<int>> result;
		for (int i = 1; i <= mid; ++i)
		{
			j = i;
			while (num < sum)
			{
				tmp.push_back(j);
				num += j++;
				if (num == sum)
				{
					result.push_back(tmp);
				}
			}
			tmp.clear();
			num = 0;
		}
		return result;
	}
};

36.和为S的两个数字_

设置下标 i,j 。

while循环分别从头开始i++ 尾 j-- 开始往中间靠拢,

如果i,j下标对应的值的和为sum压入vector tmp,然后取tmp和result的较小值赋给result(自定义比较规则)

tmp清空,++i,–j

如果i,j下标对应的值的和小于sum,++i,

如果i,j下标对应的值的和大于sum,–j。

class Solution
{
public:
	static bool cmp(vector<int> a, vector<int> b)
	{
		int aa = a[0] * a[1];
		int bb = b[0] * b[1];
		return aa < bb;
	}
	vector<int> FindNumbersWithSum(vector<int> array, int sum)
	{
		vector<int> result;
		if (array.empty() || sum <= array[0])
		{
			return result;
		}
		vector<int> tmp;
		int i = 0, j = array.size() - 1;
		while (i < j)
		{
			if (array[i] + array[j] == sum)
			{
				tmp.push_back(array[i]);
				tmp.push_back(array[j]);
				if (result.empty())
				{
					result = tmp;
				}
				result = min(tmp, result, cmp);
				tmp.clear();
				++i;
				--j;
			}
			else if (array[i] + array[j] < sum)
			{
				++i;
			}
			else
			{
				--j;
			}
		}
		return result;
	}
};

37.左旋转字符串_

使用substr截取字符串的前n位,然后将str的前n位使用erase删除,最后在末尾拼接截取的字符串

class Solution
{
public:
	string LeftRotateString(string str, int n)
	{
		if (n > str.length() || n < 0)
		{
			return "";
		}
		string rhs = str.substr(0, n);
		str.erase(0, n);
		str = str + rhs;
		return str;
	}
};

38.翻转单词序列_

先用reverse将整个字符串翻转,

for循环内,加while循环计算出两个空格之间的距离,

然后将其作为头尾,翻转字符串

class Solution {
public:
    string ReverseSentence(string str) {
        reverse(str.begin(),str.end());
        int j = 0;
        for(int i = 0; i < str.length(); ++i){
                j = i;
                while(j < str.length() && str[j] != ' '){
                    j++;
                }
                reverse(str.begin()+i,str.begin()+j);
                i = j;
        }
        return str;
    }
};

39.扑克牌顺子_

sort排序,for循环找到0的个数,for循环查看是否重复,重复返回false

如果0的个数为4直接返回true,

如果不是4,进行for循环查看是否重复,重复返回false,

不重复返回最后一个值-下标为count的值 <= 4

class Solution
{
public:
	bool IsContinuous(vector<int> numbers)
	{
		int count = 0;
		int size = numbers.size();
		sort(numbers.begin(), numbers.end());
		for (auto i : numbers)
		{
			if (i == 0)
			{
				count++;
			}
		}
		if (count == 4)
		{
			return true;
		}
		else
		{
            for (int i = count; i < size; ++i)
		{
			if (numbers[i] == numbers[i + 1])
			{
				return false;
			}
		}
			return (numbers[size - 1] - numbers[count]) <= 4;
		}
	}
};

40.孩子们的游戏(圆圈中最后剩下的数)_

1.建队列,循环压入0至n-1,

while循环m-1次,将队头抛出,再压入队尾,

然后将队头抛出,j置0,再次开始while循环,直到队列的size() 为1

class Solution {
public:
    int LastRemaining_Solution(int n, int m) {
        if(n==0 || m == 0){
            return -1;
        }
        queue<int> child;
        for(int i = 0; i < n; ++i){
            child.push(i);
        }
        int tmp = 0;
        int j = 0;
        while(child.size() > 1){
            while(j < m-1){
                tmp = child.front();
                child.pop();
                child.push(tmp);
                j++;
            }
            child.pop();
            j = 0;
        }
        return child.front();
    }
};

class Solution { 
public:
    int LastRemaining_Solution(int n, int m) {
        if(!n || !m){
            return -1;
        }
        int j = 0;
        for(int i = 2; i <= n; ++i){
            j = (j+m)%i;
        } 
        return j;
    }
};

41.求1+2+3+…+n_

使用&&表示左右两边均成立,

左边为条件n>1,

右边递归n+=函数体(n-1)

class Solution {
public:
    int Sum_Solution(int n) {
        bool x = n > 1 && (n += Sum_Solution(n-1));
        return n;
    }
};

42.不用加减乘除做加法_

使用^计算两个数二进制的无进位和,进位和,

然后再次用^计算得到的无进位和,进位和,

直到进位和为0,返回无进位和

class Solution {
public:
    int Add(int num1, int num2) {
        int c = 0;
        while(num2 != 0){
            c = (unsigned int)(num1 & num2) << 1;//进位为0结束
            num1 ^= num2;
            num2 = c;
        }
        return num1;

    }
};

43把字符串转换成整数_

先while循环将字符串前空格排除下标定在第一次出现字符的地方

判定第一个字符为数字,+,-

设置bool类型变量保存第一个字符为+,数字。还是 -

如果第一个字符不为数字下标后移一位

从下标开始for循环,每次判定字符是否为数字,

sum=sum*10+下标所指字符,

如果sum超过INT_MAX,且为正,sum= INT_MAX

如果sum超过INT_MAX+1,且为负,sum= INT_MAX+1

最后根据保存±的bool变量判定符号

class Solution {
public:
    int StrToInt(string str) {
        if(str.empty()){
            return 0;
        }
        int i = 0;
        while(i<str.length() && str[i] == ' '){ ++i;}
        if(!isdigit(str[i]) && str[i] != '+' && str[i] != '-'){
                return 0;
        }
        bool neg = (str[i] == '-' ? true : false);
        i = isdigit(str[i]) ? i : i+1;
        long long sum = 0L;
        for(; i < str.length(); ++i){
            if(!isdigit(str[i])){
                return 0;
            }else{
                sum = sum*10 + (str[i]-'0');
                if(!neg && sum > INT_MAX){
                    sum = INT_MAX;
                    break;
                }
                if(neg && sum > 1L + INT_MAX){
                    sum = 1L + INT_MAX;
                    break;
                }
            }
        }
        return neg ? static_cast<int>(-sum) : static_cast<int>(sum);
    }
};

44.数组中重复的数字_

建立unordered_map mp,for循环压入mp(++mp[val]),

for循环将mp不等于1的val值返回

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param numbers int整型vector 
     * @return int整型
     */
    int duplicate(vector<int>& numbers) {
        // write code here
        if(numbers.empty()){ return -1;}
        unordered_map<int, int> mp;
        for(auto val: numbers){
            ++mp[val];
        }
        for(int i = 0; i < numbers.size(); ++i){
            if(mp[numbers[i]] != 1){
                return numbers[i];
            }
        }
        return -1;
    }
};

45.构建乘积数组_

两个for循环嵌套,内循环进行叠乘(判定条件为当前内循环j != 外循环i),内循环结束将叠乘结果压入vector,sum置0

class Solution {
public:
    vector<int> multiply(const vector<int>& A) {
        vector<int> result;
        if(A.empty() || A.size()==1){
            return result;
        }
        int sum = 1;
        for(int i = 0; i < A.size(); ++i){
            for(int j = 0; j < A.size(); ++j){
                if(i != j){
                    sum *= A[j];
                }
            }
            result.push_back(sum);
            sum = 1;
        }
        return result;
    
    }
};

46.正则表达式匹配_

1.两者为空返回true

2.str不为空,pattern为空返回false

3.如果pattern下一位不为*,如果当前位str = pattern 或者(str不为空且pattern为.)返回函数str+1,pattern+1递归,否则返回false

4.如果pattern下一位为*,如果当前位str = pattern 或者(str不为空且pattern为.)返回函数pattern+2递归,或者str+1递归,

否则返回pattern+2递归

class Solution {
public:
    /* 分清楚情况 */
    bool match(char* str, char* pattern)
    {
        if(*str == '\0' && *pattern == '\0')//两者都为空 true
            return true;
        if(*str != '\0' && *pattern == '\0')//str不空 patten空
            return false;
        
        if(*(pattern + 1) != '*'){
            //匹配.下一位
            if(*str == *pattern || (*str != '\0' && *pattern == '.'))
                return match(str + 1, pattern + 1);
            else
                return false;
        }
        else {  //下一个字符为'*'
            if(*str == *pattern || (*str != '\0' && *pattern == '.'))
                return match(str, pattern + 2) //  .*代表0次时
                    || match(str + 1, pattern);// 跳过和匹配多个的情况
            else
                return match(str, pattern + 2);//字符不匹配,则模式向后移动2位
        }
    }
};

47.表示数值的字符串_

判断e/E存在的情况

判断+/-存在的情况

判断 . 存在的情况

判断除上述外是数字的情况

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param str string字符串 
     * @return bool布尔型
     */
    bool isNumeric(string str) {
        int len = str.length();
        bool hasM = false;
        bool hasE = false;
        bool hasP = false;
        for(int i = 0; i < len; ++i){
            if(str[i] == 'e' || str[i] == 'E'){
                if( str[i-1] == '+' || str[i-1] == '-'){
                    return false;
                }
                if( hasE || i == len - 1 ){
                return false;
                }
                hasE = true;
            }else if(str[i] == '+' || str[i] == '-'){
                if( i == len -1){
                    return false;
                }
                if(hasM && str[i-1] != 'e' && str[i-1] != 'E'){
                    return false;
                }
                if(!hasM && i != 0 && str[i-1] != 'e' && str[i-1] != 'E'){
                    return false;
                }
                hasM = true;
            }else if(str[i] == '.'){
                if(hasE || hasP){
                    return false;
                }
                if( i == 0 || i == len - 1){
                    return false;
                }else if(str[i-1] < '0' || str[i-1] > '9'){
                    return false;
                }else if(str[i+1] < '0' || str[i+1] > '9'){
                    return false;
                }
                hasP = true;
            }else if(str[i] < '0' || str[i] > '9'){
                return false;
            }
        }
        return true;
    }
};

48.字符流中第一个不重复的字符_

如果mp中没找到,就压入队列

循环取队头,如果在mp中出现一次返回,否则抛出

循环无结果返回#

class Solution
{
public:
    unordered_map<char, int> mp;
    queue<char> q;
  //Insert one char from stringstream
    void Insert(char ch) {
         if(mp.find(ch) == mp.end()){
             q.push(ch);
         }
        ++mp[ch];
    }
  //return the first appearence once char in current stringstream
    char FirstAppearingOnce() {
        while(!q.empty()){
            char ch = q.front();
            if(mp[ch] == 1){
                return ch;
            }
            else{
                q.pop();
            }
        }
        return '#';
    }
};

49.链表中环的入口结点_

将节点存入set

循环查找set中是否存在节点,存在返回节点,不存在压入节点

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        unordered_set<ListNode*> set;
        while(pHead){
            if(set.find(pHead) == set.end()){
                set.insert(pHead);
                pHead = pHead->next;
            }else{
                return pHead;
            }
        }
        return nullptr;
    }
};

50.删除链表中重复的结点_

定义一个节点在pHead之前

出现重复,p=p->next,循环p=p->next,再次p=p->next,使q的下一个指向p

没有出先重复去q=p,p=p->next

返回开头定义节点的下一个

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead) {
        ListNode* vHead = new ListNode(-1);
        vHead->next = pHead;
        ListNode* p = pHead;
        ListNode* q = vHead;
        while(p){
            if(p->val == p->next->val && p->next){
                p = p->next;
                while(p->val == p->next->val && p->next){
                    p = p->next;
                }
                p = p->next;
                q->next = p;
            }else{
                q = p;
                p = p->next;
            }
        }
        return vHead->next;
    }
};

51.二叉树的下一个结点_

节点有右子树,跳到右子树,往左找,有返回,无返回自己

如果节点有父节点,且节点为父节点的左节点,返回父节点 ,节点跳到父节点

直接返回空

/*
struct TreeLinkNode {
    int val;
    struct TreeLinkNode *left;
    struct TreeLinkNode *right;
    struct TreeLinkNode *next;
    TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
        
    }
};
*/
class Solution {
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode) {
        if(!pNode){
            return pNode;
        }
        if(pNode->right){
            pNode = pNode->right;
            while(pNode->left){
                pNode = pNode->left;
            }
            return pNode;
        }
        
        while(pNode->next){
            TreeLinkNode* root = pNode->next;
            if(root->left == pNode){
                return root;
            }
            pNode = pNode->next;
        }
        
        return nullptr;
    }
};

52.对称的二叉树_

root->left->val == root->right->val

&& root->left->left->val == root->right->right->val

&& root->left->right->val == root->right->left->val

做递归 直到两边都结束

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot) {
        return isSame(pRoot, pRoot);
    
    }
    bool isSame(TreeNode* p,TreeNode* q){
        if(!p && !q) return true;
        if(!p || !q) return false;
        return p->val == q->val 
            && isSame(p->left, q->right) 
            && isSame(p->right, q->left);
    }

};

53.按之字形顺序打印二叉树_

类似一行一行打印二叉树,增加一个变量判断从左还是从右

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {
        queue<TreeNode*> q;
        vector<int> tmp;
        vector<vector<int>> result;
        int level = 0;
        if(!pRoot){
            return result;
        }
        q.push(pRoot);
        while(!q.empty()){
            int size = q.size();
            while(size--){
                TreeNode* t = q.front();
                tmp.push_back(t->val);
                q.pop();
                if(t->left) {q.push(t->left);}
                if(t->right) {q.push(t->right);}
            }
            ++level;
            if(!(level&1))//奇数&1为1,偶数&1为0
                reverse(tmp.begin(), tmp.end());
            result.push_back(tmp);
            tmp.clear();
        }
        return result;
    }
    
};

54.把二叉树打印成多行_

上面去掉左右判断

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
        vector<vector<int> > Print(TreeNode* pRoot) {
            vector<vector<int>> result;
            if(!pRoot){ return result;}
            vector<int> tmp;
            queue<TreeNode*> q;
            q.push(pRoot);
            while(!q.empty()){
                int size = q.size();
                while(size--){
                    TreeNode* t = q.front();
                    q.pop();
                    tmp.push_back(t->val);
                    if(t->left){ q.push(t->left);}
                    if(t->right){ q.push(t->right);}
                }
                result.push_back(tmp);
                tmp.clear();
            }
            return result;
        
        }
    
};

55.序列化二叉树_

先将树前序遍历

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    char* Serialize(TreeNode *root) {    
        if(!root){ return "#";}
        string str = to_string(root->val);
        str.push_back(',');
        char* left = Serialize(root->left);
        char* right = Serialize(root->right);
        char* ret = new char[strlen(left) + strlen(right) + str.size()];
        strcpy(ret, str.c_str());
        strcat(ret, left);
        strcat(ret, right);
        return ret;
    }
    TreeNode* deseri(char* &s){//引用
        if(*s == '#'){
            ++s;
            return nullptr;
        }
        int num = 0;
        while(*s != ','){
            num = num * 10 + (*s - '0');
            ++s;
        }
        ++s;
        TreeNode* root = new TreeNode(num);
        root->left = deseri(s);
        root->right = deseri(s);
        return root;
    }
    TreeNode* Deserialize(char *str) {
        return deseri(str);
    }
};

56.二叉搜索树的第k个结点_

二叉搜索树(左<根<右)

先中序遍历压入栈,

根据栈大小抛出

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    stack<TreeNode*> s;
    void pushRoot(TreeNode* root){
        if(root){
            pushRoot(root->left);
            s.push(root);
            pushRoot(root->right);
        }
    }
    TreeNode* KthNode(TreeNode* pRoot, int k) {
        if(!pRoot || k <= 0) { return nullptr;}
        pushRoot(pRoot);
        if(s.size() < k ){ return nullptr;}
        while(s.size() > k){
            s.pop();
        }
        return s.top();
    }
};

57.数据流中的中位数_

class Solution {
public:
    vector<int> vec;
    void Insert(int num) {
        if(vec.empty()){
            vec.push_back(num);
        }else{
            auto it = lower_bound(vec.begin(), vec.end(), num);
            vec.insert(it, num);
        }
    }

    double GetMedian() { 
        int size = vec.size();
        double ret = 0.00;
        if(size%2 == 0){
            ret = static_cast<double>(vec[size>>1] + vec[(size-1)>>1])/2;
        }else{
            ret = static_cast<double>(vec[size>>1]);
        }
        return ret;
    }

};

58.滑动窗口的最大值_

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
        vector<int> result;
        if(num.empty() || num.size() < size || size < 1){
            return result;
        }
        int max_num = INT_MIN;
        deque<int> dq;
        for(int i = 0; i < num.size(); ++i){
            while(!dq.empty() && num[dq.back()] < num[i]){
                dq.pop_back();
            }
            dq.push_back(i);
           if(dq.front() + size <= i){
               dq.pop_front();
           }
            if(i + 1 >= size){
                result.push_back(num[dq.front()]);
            }
        }
        return result;
        
    }
};

59.二维数组中的查找_

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int m = array.size();
     if (m == 0) return false;
     int n = array[0].size();
     if (n == 0) return false;
     int r = 0, c = n-1; // 右上角元素
     while (r<m && c>=0) {
         if (target == array[r][c]) {
             return true;
         }
         else if (target > array[r][c]) {
             ++r;
         }
         else {
             --c;
         }
    }
     return false;
    }
};

60.替换空格_

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param s string字符串 
     * @return string字符串
     */
    string replaceSpace(string s) {
        // write code here
        int len = s.length();
        if(len < 1){
            return "";
        }
        for(int i = 0; i < s.length(); ++i){
            if(s[i] == ' '){
                s.replace(i, 1, "%20");
                s.resize(s.length()+2);
            }
        }
        return s;
    }
};

61.从尾到头打印链表_

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> result;
        stack<int> s;
        if(!head){
            return result;
        }
        while(head){
            s.push(head->val);
            head = head->next;
        }
        while(!s.empty()){
            result.push_back(s.top());
            s.pop();
        }
        return result;
    }
};

62.重建二叉树_

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* rebuild(vector<int>& pre, int pre_left, int pre_right, vector<int>& vin, int vin_left, int vin_right) {
        if (pre_left > pre_right||vin_left > vin_right) return nullptr;
 
        TreeNode* root = new TreeNode(pre[pre_left]);
        for (int i=vin_left; i<=vin_right; ++i) {
            if (vin[i] == root->val) {
                root->left = rebuild(pre, pre_left+1, pre_left+i-vin_left, vin, vin_left, i-1);
                root->right = rebuild(pre, pre_left+i-vin_left+1, pre_right, vin, i+1, vin_right);
                break;
            }
        }
        return root;
    }
    TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
        return rebuild(pre, 0, pre.size()-1, vin, 0, vin.size()-1);
    }
};

63.用两个栈实现队列_

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        int ret = stack2.top();
        stack2.pop();
        return ret;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

64.旋转数组的最小数字_

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if (rotateArray.size() == 0) return 0;
        int first = 0, last = rotateArray.size() - 1;
        while (first < last) { // 最后剩下一个元素,即为答案
            if (rotateArray[first] < rotateArray[last]) { // 提前退出
                return rotateArray[first];
            }
            int mid = first + ((last - first) >> 1);
            if (rotateArray[mid] > rotateArray[last]) { // 情况1
                first = mid + 1;
 
            }
            else if (rotateArray[mid] < rotateArray[last]) { //情况2
                last = mid;
            }
            else { // 情况3
                --last;
            }
        }
        return rotateArray[first];
    }
};
string abbreviation(string a, string b) {
    int alen = a.length();
    int blen = b.length();
    int i = 0, j = 0;
    while(i < alen && j < blen){
        if(a[i] == b[j] || a[i] == (b[j] + 32)){
            i++;
            j++;
        }else{
            if(islower(a[i])){
                i++;
            }else{
                return "NO";
            }            
        }
    }
    while(i < alen){
        if(islower(a[i])){
            i++;
        }else{
            return "NO";
        }
    }
    if(j < blen){
        return "NO";
    }else{
        return "YES";
    }
}
```c

     for (int i=vin_left; i<=vin_right; ++i) {
            if (vin[i] == root->val) {
                root->left = rebuild(pre, pre_left+1, pre_left+i-vin_left, vin, vin_left, i-1);
                root->right = rebuild(pre, pre_left+i-vin_left+1, pre_right, vin, i+1, vin_right);
                break;
            }
        }
        return root;
    }
    TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
        return rebuild(pre, 0, pre.size()-1, vin, 0, vin.size()-1);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值