#include
#include
using namespace std;
int duplicate(vector<int>& numbers) {
vector<int> counter(numbers.size(), 0);
for(int i = 0; i < numbers.size(); ++i) {
if(counter[numbers[i]] >= 1) {
return numbers[i];
}
else {
++counter[numbers[i]];
}
}
return -1;
}
int main(int argc, const char * argv[]) {
vector<int> numbers{2, 3, 1, 0, 6, 5, 4};
cout << duplicate(numbers) << endl;
return 0;
}
#include
#include
using namespace std;
bool find(int target, vector<vector<int>> numbers) {
// 当前行、列
int x = 0, y = (int)(numbers[x].size() - 1);
while(x < numbers.size() && x >=0 && y <numbers[x].size() && y >= 0) {
if(numbers[x][y] == target) {
return true;
}
else if(numbers[x][y] < target) {
++x;
}
else {
--y;
}
}
return false;
}
int main(int argc, const char * argv[]) {
vector<vector<int>> numbers{{1, 3, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
cout << find(0, numbers) << endl;
return 0;
}
s
中的每个空格替换成“%20
”。We Are Happy
,则经过替换之后的字符串为We%20Are%20Happy
。s == ' '
而不是s == " "
。#include
#include
using namespace std;
string repalceSpace(string s) {
string ns = "";
for(int i = 0; i < s.length(); ++i) {
if(s[i] == ' ') {
ns += "%20";
}
else {
ns += s[i];
}
}
return ns;
}
int main(int argc, const char * argv[]) {
string s = "We are happy.";
cout << repalceSpace(s) << endl;
return 0;
}
vector
有了新的认识…#include
#include
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
ListNode* current = head;
while(current != NULL) {
result.insert(result.begin(), current->val);
current = current->next;
}
return result;
}
int main(int argc, const char * argv[]) {
ListNode* n1 = new ListNode(2);
ListNode* n2 = new ListNode(1);
ListNode* n3 = new ListNode(3);
ListNode* n4 = new ListNode(0);
ListNode* n5 = new ListNode(10);
n1->next = n2;
n2->next = n3;
n3->next = n4;
n4->next = n5;
vector<int> result = printListFromTailToHead(n1);
for(auto i : result) {
cout << i << endl;
}
delete n1, n2, n3, n4, n5;
return 0;
}
#include
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
// 边界情况检查
if(pre.empty() || vin.empty()) {
return NULL;
}
// 前序遍历序列第一个元素一定是根节点
int rootValue = pre[0];
TreeNode* root = new TreeNode(rootValue);
// 在中序遍历序列中找根节点
vector<int>::iterator rootIndexInVin = find(vin.begin(), vin.end(), rootValue);
int leftPreLen = rootIndexInVin - vin.begin();
// 构造左右子树的前序遍历序列和中序遍历序列
if(leftPreLen > 0) {
vector<int> leftPre(pre.begin() + 1, pre.begin() + 1 + leftPreLen);
vector<int> leftVin(vin.begin(), vin.begin() + leftPreLen);
root->left = reConstructBinaryTree(leftPre, leftVin);
}
if(leftPreLen < vin.size() - 1) {
vector<int> rightPre(pre.begin() + 1 + leftPreLen, pre.end());
vector<int> rightVin(vin.begin() + 1 + leftPreLen, vin.end());
root->right = reConstructBinaryTree(rightPre, rightVin);
}
return root;
}
int main(int argc, const char * argv[]) {
vector<int> pre{1,2,4,7,3,5,6,8};
vector<int> vin{4,7,2,1,5,3,8,6};
TreeNode* root = reConstructBinaryTree(pre, vin);
return 0;
}
题目描述:给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。
解题思路:中序遍历即按照左子节点、根节点、右子节点的顺序访问树。因此:
如果该节点有右子树,那么该节点的下一个节点右子树中的最左节点;
如果该节点没有右子树,则该节点的下一个节点是——该节点的祖父节点集合中属于其父节点的左节点的点的父节点,例如下图中的节点 i i i,节点 b , e , a b,e,a b,e,a都是其祖父节点,往上一层层寻找的过程中,发现第一组出现父节点、左子节点的关系的节点是 b b b和 a a a,因此 a a a是 i i i的下一个前序遍历节点。
当然还有一种很笨的方法,就是直接找到根节点,然后在前序遍历队列中查找。
#include
using namespace std;
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {}
};
TreeLinkNode* GetNext(TreeLinkNode* pNode) {
// 边界情况检查
if(pNode == NULL) {
return NULL;
}
// 有右子树,那么该节点的下一个节点右子树中的最左节点
if(pNode->right != NULL) {
pNode = pNode->right;
while(pNode->left != NULL) {
pNode = pNode->left;
}
return pNode;
}
// 没有右子树,则该节点的下一个节点是该节点的父节点集合中属于其父节点的左节点的点的父节点
else {
while(pNode->next != NULL) {
if(pNode->next->left == pNode) {
return pNode->next;
}
else {
pNode = pNode->next;
}
}
}
// 查找到树的根节点都找不到的话就没了
return NULL;
}
int main(int argc, const char * argv[]) {
TreeLinkNode* a = new TreeLinkNode(0);
TreeLinkNode* b = new TreeLinkNode(1);
TreeLinkNode* c = new TreeLinkNode(2);
TreeLinkNode* d = new TreeLinkNode(3);
TreeLinkNode* e = new TreeLinkNode(4);
TreeLinkNode* f = new TreeLinkNode(5);
TreeLinkNode* g = new TreeLinkNode(6);
TreeLinkNode* h = new TreeLinkNode(7);
TreeLinkNode* i = new TreeLinkNode(8);
a->left = b;
a->right = c;
b->left = d;
b->right = e;
b->next = a;
c->left = f;
c->right = g;
c->next = a;
d->next = b;
e->left = h;
e->right = i;
e->next = b;
f->next = c;
g->next = c;
h->next = e;
i->next = e;
cout << GetNext(i)->val << endl;
return 0;
}
#include
#include
using namespace std;
stack<int> stack1;
stack<int> stack2;
void push(int node) {
stack1.push(node);
}
int pop() {
if(stack2.empty()) {
while (!stack1.empty()) {
stack2.push(stack1.top());
stack1.pop();
}
}
int node = stack2.top();
stack2.pop();
return node;
}
int main(int argc, const char * argv[]) {
push(0);
push(1);
cout << pop() << endl;
cout << pop() << endl;
push(2);
cout << pop() << endl;
push(3);
cout << pop() << endl;
push(4);
push(5);
push(6);
push(7);
cout << pop() << endl;
cout << pop() << endl;
push(8);
push(9);
cout << pop() << endl;
cout << pop() << endl;
cout << pop() << endl;
cout << pop() << endl;
return 0;
}
class Solution {
public:
int Fibonacci(int n) {
if (n > 2) {
int a = 0, b = 1, c = 1, d; //第i-2,i-2,i个数和中间量
for (int i = 3; i <= n; i++) {
d = c;
c = c + b;
a = b;
b = d;
}
return c;
} else if (n == 1) {
return 0;
} else {
return 1;
}
}
};
#include
#include
using namespace std;
int minNumberInRotateArray(vector<int> rotateArray) {
// 检测非法输入
if(rotateArray.empty()) {
return 0;
}
if(rotateArray[0] < rotateArray[rotateArray.size() - 1]) {
return rotateArray[0];
}
// 子问题
if(rotateArray.size() == 1) {
return 0;
}
if(rotateArray.size() == 2) {
if(rotateArray[0] > rotateArray[1]) {
return rotateArray[1];
}
else {
return 0;
}
}
// 分割数组
int right = rotateArray.size() / 2;
int left = right - 1;
int last = rotateArray.size() - 1;
// 终止条件
if(rotateArray[left] > rotateArray[right]) {
return rotateArray[right];
}
// 二分法
// 如果左边的最后一个数大于等于右边的最后一个数,那么最小值肯定在右侧数组
if (rotateArray[left] > rotateArray[last]) {
vector<int> newRotateArray(rotateArray.begin() + right, rotateArray.end());
return minNumberInRotateArray(newRotateArray);
}
// 如果左边的最后一个数小于右边的最后一个数,那么最小值肯定在左侧数组
else if (rotateArray[left] < rotateArray[last]){
vector<int> newRotateArray(rotateArray.begin(), rotateArray.begin() + left + 1);
return minNumberInRotateArray(newRotateArray);
}
// 如果左边的最后一个数等于右边的最后一个数,不能判断最小值在左在右,可使用缩减边界法
else {
while(rotateArray[left] == rotateArray[last] && left < last) {
--last;
}
vector<int> newRotateArray(rotateArray.begin(), rotateArray.begin() + last + 1);
return minNumberInRotateArray(newRotateArray);
}
}
int main(int argc, const char * argv[]) {
vector<int> array0{3, 4, 5, 1, 2};
vector<int> array1{1, 1, 1, 1, 0, 1};
vector<int> array2{2, 2, 2, 1, 2};
vector<int> array3{1, 1, 2, 2, 2, 2, 2, 1};
vector<int> array4{2, 2, 1, 2, 2, 2};
vector<int> array5{1, 0, 1, 1, 1, 1};
cout << minNumberInRotateArray(array0) << endl;
cout << minNumberInRotateArray(array1) << endl;
cout << minNumberInRotateArray(array2) << endl;
cout << minNumberInRotateArray(array3) << endl;
cout << minNumberInRotateArray(array4) << endl;
cout << minNumberInRotateArray(array5) << endl;
return 0;
}
#include
#include
#include
#include
using namespace std;
// 深度优先搜索
bool search(vector<vector<char>>& matrix, string word, int x, int y, vector<vector<bool>> searched) {
// 是否已经没有待查找元素
if(word.empty()) {
return true;
}
// 设置当前位置为已查找
vector<vector<bool>> newSearched(searched);
newSearched[x][y] = true;
// 去掉字符串首元素
char beginChar = word[0];
string newWord(word.begin() + 1, word.end());
// 向四个方向搜索
if(x > 0) {
if(!searched[x][y] && matrix[x - 1][y] == beginChar) {
if(search(matrix, newWord, x - 1, y, newSearched)) {
return true;
}
}
}
if(x < matrix.size() - 1) {
if(!searched[x + 1][y] && matrix[x + 1][y] == beginChar) {
if(search(matrix, newWord, x + 1, y, newSearched)) {
return true;
}
}
}
if(y > 0) {
if(!searched[x][y - 1] && matrix[x][y - 1] == beginChar) {
if(search(matrix, newWord, x, y - 1, newSearched)) {
return true;
}
}
}
if(y < matrix[x].size() - 1) {
if(!searched[x][y + 1] && matrix[x][y + 1] == beginChar) {
if(search(matrix, newWord, x, y + 1, newSearched)) {
return true;
}
}
}
return false;
}
bool hasPath(vector<vector<char>>& matrix, string word) {
// 非法检测
if(matrix.empty() || word.empty()) {
return false;
}
// 去掉字符串首元素
char beginChar = word[0];
string newWord(word.begin() + 1, word.end());
// 构造已查找矩阵
vector<vector<bool>> searched(matrix.size());
for(int i = 0; i < matrix.size(); ++i) {
vector<bool> temp(matrix[i].size(), false);
searched[i] = temp;
}
// 先找到第一个字母的位置(x, y),可能有多个
for(int i = 0; i < matrix.size(); ++i) {
for(int j = 0; j < matrix[i].size(); ++j) {
if(matrix[i][j] == beginChar) {
vector<vector<bool>> newSearched(searched);
if(search(matrix, newWord, i, j, newSearched)) {
return true;
}
}
}
}
return false;
}
int main(int argc, const char * argv[]) {
vector<vector<char>> matrix{{'a','b','c','e'},{'s','f','c','s'},{'a','d','e','e'}};
cout << hasPath(matrix, "abcced") << endl;
cout << hasPath(matrix, "abcb") << endl;
return 0;
}
#include
#include
using namespace std;
vector<vector<bool>> counted;
bool judge(int threshold, int x, int y) {
int count = 0;
while(x != 0) {
count += x % 10;
x = x / 10;
}
while(y != 0) {
count += y % 10;
y = y / 10;
}
return count <= threshold;
}
int search(int threshold, int rows, int cols, int x, int y) {
counted[x][y] = true;
int count = 0;
if(judge(threshold, x, y)) {
++count;
}
else {
return count;
}
if(x > 0) {
if(!counted[x - 1][y]) {
count += search(threshold, rows, cols, x - 1, y);
}
}
if(x < rows - 1) {
if(!counted[x + 1][y]) {
count += search(threshold, rows, cols, x + 1, y);
}
}
if(y > 0) {
if(!counted[x][y - 1]) {
count += search(threshold, rows, cols, x, y - 1);
}
}
if(y < cols - 1) {
if(!counted[x][y + 1]) {
count += search(threshold, rows, cols, x, y + 1);
}
}
return count;
}
int movingCount(int threshold, int rows, int cols) {
// 记录哪些格子已经被查找过了
counted.clear();
for(int i = 0; i < rows; ++i) {
vector<bool> temp(cols, false);
counted.push_back(temp);
}
return search(threshold, rows, cols, 0, 0);
}
int main(int argc, const char * argv[]) {
cout << movingCount(1, 2, 3) << endl;
cout << movingCount(0, 1, 3) << endl;
cout << movingCount(5, 10, 10) << endl;
return 0;
}
#include
using namespace std;
int cutRope(int n) {
// 一些最小子问题
if(n == 2) {
return 1;
}
else if(n == 3) {
return 2;
}
// dp[i]代表了长度为i的绳子分割为m段之后最大的乘积
int* dp = new int[n + 1];
memset(dp, 0, (n + 1) * sizeof(int));
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
// 开始动态规划
for(int ni = 4; ni <= n; ++ni) {
for(int nii = 1; nii < ni; ++nii) {
dp[ni] = max(dp[ni], dp[nii] * dp[ni - nii]);
}
}
// 删除资源并输出
int result = dp[n];
delete [] dp;
return result;
}
int main(int argc, const char * argv[]) {
cout << cutRope(3) << endl;
cout << cutRope(5) << endl;
cout << cutRope(6) << endl;
cout << cutRope(8) << endl;
return 0;
}
#include
int numOfBits = 32;
int NumberOf1(int n) {
int result = 0;
// 正数
if(n > 0) {
while(n != 0) {
if(n % 2 == 1) {
++result;
}
n = n / 2;
}
}
// 负数
else if(n < 0) {
// 初始化编码数组
int* code = new int[numOfBits];
memset(code, 0, numOfBits * sizeof(int));
// 符号位为1
code[numOfBits - 1] = 1;
// 求原码(与正数相同)
n = -n;
for(int i = 0; n != 0; ++i) {
if(n % 2 == 1) {
code[i] = 1;
}
n = n / 2;
}
// 求反码(除符号位外都取反)
for(int i = 0; i < numOfBits - 1; ++i) {
if(code[i] == 1) {
code[i] = 0;
}
else {
code[i] = 1;
}
}
// 求补码并统计(补码等于反码加1)
bool flag = true; // 进位标志
for(int i = 0; i < numOfBits - 1; ++i) {
if(flag) {
code[i] += 1;
if(code[i] >= 2) {
flag = true;
code[i] = code[i] % 2;
}
else {
flag = false;
}
}
if(code[i] == 1) {
++result;
}
}
// 算上符号位
++result;
}
return result;;
}
int main(int argc, const char * argv[]) {
std::cout << NumberOf1(3) << std::endl; // 2
std::cout << NumberOf1(1024) << std::endl; // 1
std::cout << NumberOf1(-3) << std::endl; // 31
std::cout << NumberOf1(-1) << std::endl; // 32
return 0;
}
#include
double Power(double base, int exponent) {
// 0的任意次方是0
if(base == 0) {
return 0;
}
// 任意数的0次方都是1
if(exponent == 0) {
return 1;
}
double result = 1;
// 指数为正
if(exponent > 0) {
while(exponent--) {
result *= base;
}
}
// 指数为负
else {
while(exponent++) {
result /= base;
}
}
return result;
}
int main(int argc, const char * argv[]) {
std::cout << Power(2.00000, 3) << std::endl; // 8
std::cout << Power(-9.00000, 3) << std::endl; // -729
std::cout << Power(-1.10000, 2) << std::endl; // 1.21
std::cout << Power(-2.00000, -2) << std::endl; // 0.25
return 0;
}
#include
#include
#include
using namespace std;
vector<int> printNumbers(int n) {
vector<int> result;
for(int i = 1; i < pow(10, n); ++i) {
result.push_back(i);
}
return result;
}
int main(int argc, const char * argv[]) {
vector<int> result = printNumbers(3);
return 0;
}
#include
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* deleteNode(ListNode* head, int val) {
// 如果删除的是首节点,直接返回第二个节点就够了
if(val == head->val) {
return head->next;
}
// 寻找被删除节点并删除(虚假的删除)
ListNode* pre = head;
ListNode* now = head->next;
while(val != now->val) {
pre = now;
now = now->next;
}
pre->next = now->next;
return head;
}
int main(int argc, const char * argv[]) {
ListNode* a = new ListNode(2);
ListNode* b = new ListNode(5);
ListNode* c = new ListNode(1);
ListNode* d = new ListNode(9);
a->next = b;
b->next = c;
c->next = d;
deleteNode(a, 1);
cout << a->val << ", " << a->next->val << ", " << a->next->next->val << endl;
delete a;
delete b;
delete c;
delete d;
return 0;
}
'.'
和'*'
的正则表达式。'.'
表示任意一个字符'*'
表示它前面的字符可以出现任意次(包含0次)。"aaa"
与模式"a.a"
和"ab*ac*a"
匹配,但是与"aa.a"
和"ab*a"
均不匹配。'.'
,但没有连续的'*'
。题目其实并不难,难点在于如何编程实现,思路一定要清晰。还是可以使用深度优先搜索来解决这个问题。
三个退出条件:
'*'
;三种匹配状况:
'*'
:这种情况必须先处理,因为'*'
前面会跟着字符或者'.'
,如果不先处理的话会与其他情况混淆。这种情况又分为'*'
前面跟着字符或者'.'
。'.'
:这种情况最简单——跳过当前字符就可以了。建议跟着我的代码/注释捋一捋思路。
#include
using namespace std;
// 深度优先搜索
bool match(string str, string pattern) {
// 三个退出条件
// 如果二者中都为空说明匹配成功
if(str.empty() && pattern.empty()) {
return true;
}
// 如果模式为空而字符不为空说明匹配失败
if(!str.empty() && pattern.empty()) {
return false;
}
// 如果字符为空而模式不为空,则需要判断是否出现'*'
if(str.empty() && !pattern.empty()) {
for(int i = 0; i < pattern.length(); ++i) {
if(i + 1 < pattern.length()) {
if(pattern[i + 1] == '*') {
++i;
}
else {
return false;
}
}
else {
return false;
}
}
// 剩余模式均为'*'则匹配成功
return true;
}
// 开始匹配(注意,一定要先处理'*')
// 检测'*'
if(pattern.length() > 1 && pattern[1] == '*') {
string newPattern(pattern.begin() + 2, pattern.end());
// 处理'.*'
if(pattern[0] == '.') {
// 先处理字符出现0次
if(match(str, newPattern)) {
return true;
}
// 处理字符出现1~n次
for(int i = 0; i < str.length(); ++i) {
string newStr(str.begin() + i + 1, str.end());
if(match(newStr, newPattern)) {
return true;
}
}
}
// 处理字符和'*'
else {
// 先处理字符出现0次
if(match(str, newPattern)) {
return true;
}
// 处理字符出现1~n次
for(int i = 0; i < str.length(); ++i) {
if(str[i] == pattern[0]) {
string newStr(str.begin() + i + 1, str.end());
if(match(newStr, newPattern)) {
return true;
}
}
else {
break;
}
}
}
}
// 检测'.'
else if(pattern[0] == '.') {
string newStr(str.begin() + 1, str.end());
string newPattern(pattern.begin() + 1, pattern.end());
return match(newStr, newPattern);
}
// 普通匹配
else {
if(str[0] == pattern[0]) {
string newStr(str.begin() + 1, str.end());
string newPattern(pattern.begin() + 1, pattern.end());
return match(newStr, newPattern);
}
else {
return false;
}
}
return false;
}
int main(int argc, const char * argv[]) {
cout << match("aaab", "aaab") << endl; // 1
cout << match("a.a", "aaaa") << endl; // 0
cout << match("a.a", "aza") << endl; // 1
cout << match("aaa", "aaaz*") << endl; // 1
cout << match("aaa", "a*a") << endl; // 1
cout << match("aad", "c*a*d") << endl; // 1
cout << match("aaab", "a*a*a*c") << endl; // 0
cout << match("a", ".") << endl; // 1
return 0;
}
请实现一个函数用来判断字符串str是否表示数值(包括科学计数法的数字,小数和整数)。【时间复杂度和空间复杂度都是 O ( n ) O(n) O(n)】
科学计数法的数字(按顺序)可以分成以下几个部分:
1.若干空格
2.一个整数或者小数
3.(可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个整数(可正可负)
4.若干空格
小数(按顺序)可以分成以下几个部分:
1.若干空格
2.(可选)一个符号字符(‘+’ 或 ‘-’)
3. 可能是以下描述格式之一:
3.1 至少一位数字,后面跟着一个点 ‘.’
3.2 至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
3.3 一个点 ‘.’ ,后面跟着至少一位数字
4.若干空格
整数(按顺序)可以分成以下几个部分:
1.若干空格
2.(可选)一个符号字符(‘+’ 或 ‘-’)
3. 至少一位数字
4.若干空格
简单点的话,就是分别判断是否是三种类型,最后用或运算将结果整合起来就好了。
但是看到这个时空复杂度,就应该知道不能分成三种类型去判断,而是在一个循环中就要判断出来了。应该注意到科学技术法其实就是“小数/整数” + “E/e” + “整数”,因此题目可以简化为判断是否为小数或者整数。
思路比较难以描述,总的来说就是分类讨论:如果监测到非法输入(例如“E/e”后面出现小数点),就直接返回false
;如果函数能走到最后,则返回true
。建议看代码/注释理解吧。
不过,说实话分类讨论还是比较难的,我最开始提交的时候通过率志勇 31 / 39 31/39 31/39,后面调试了六七次…
#include
using namespace std;
bool isNumeric(string str) {
// 消除前面空格
while(!str.empty() && str[0] == ' ') {
str.erase(str.begin());
}
// 判断非法输入
if(str.empty()) {
return false;
}
// 中间变量
bool number = false; // 数字是否已出现过
bool dot = false; // 小数点是否已出现过
bool plus_minus = false; // 加减号是否出现过
bool E = false; // E和e是否出现过
// 开始判断
for(int i = 0; i < str.length(); ++i) {
// 读取到空格
if(str[i] == ' ') {
// 空格只能出现在最后面,否则什么都不是
while(++i < str.length()) {
if(str[i] != ' ') {
return false;
}
}
}
// 读取到数字
else if(str[i] - '0' >= 0 && '9' - str[i] >= 0) {
// 数字可以出现在任何地方,因此无需处理
number = true;
}
// 读取到E/e
else if(str[i] == 'E' || str[i] == 'e') {
// E/e只能有一个
if(E) {
return false;
}
// E/e前面必须是小数或者整数,即必须出现数字
if(!number) {
return false;
}
// E/e后面必须有东西且不是空格
if(i == str.length() - 1 || str[i + 1] == ' ') {
return false;
}
// 后面只能存在整数
// 加减号、数字、小数点符号应先置0
plus_minus = false;
number = false;
dot = false;
E = true;
}
// 读取到加减号
else if(str[i] == '-' || str[i] == '+') {
// 加减号不能重复出现,前面也不能有小数点,也不能有数字
if(plus_minus || dot || number) {
return false;
}
// 加减号后面必须有东西且不是空格
if(i == str.length() - 1 || str[i + 1] == ' ') {
return false;
}
plus_minus = true;
}
// 读取到小数点
else if(str[i] == '.') {
// 小数点前面不能有小数点
if(dot) {
return false;
}
// E/e后面只能是整数,因此不能出现小数点
if(E) {
return false;
}
// 小数点前面或者后面需要有数字
if(!number) {
if(i == str.length() - 1 || (str[i + 1] - '0' < 0 && '9' - str[i + 1] < 0)) {
return false;
}
}
dot = true;
}
// 检测到非法输入
else {
return false;
}
}
return true;
}
int main(int argc, const char * argv[]) {
cout << (isNumeric(" 123.45e+6") == true) << endl;
cout << (isNumeric("+100") == true) << endl;
cout << (isNumeric("5e2") == true) << endl;
cout << (isNumeric("") == false) << endl;
cout << (isNumeric("-123") == true) << endl;
cout << (isNumeric("3.1416") == true) << endl;
cout << (isNumeric("-1E-16") == true) << endl;
cout << (isNumeric("12e") == false) << endl;
cout << (isNumeric("1a3.14") == false) << endl;
cout << (isNumeric("1.2.3") == false) << endl;
cout << (isNumeric("+-5") == false) << endl;
cout << (isNumeric("12e+4.3") == false) << endl;
cout << (isNumeric(".") == false) << endl;
cout << (isNumeric(" .2") == true) << endl;
cout << (isNumeric("+ a") == false) << endl;
cout << (isNumeric(" 12e ") == false) << endl;
cout << (isNumeric(" 12 ") == true) << endl;
return 0;
}
insert
函数拼接在一起就可以了。时间、空间复杂度都是 O ( n ) O(n) O(n)。#include
#include
using namespace std;
vector<int> reOrderArray(vector<int>& array) {
vector<int> odd, even, result;
for(int i = 0; i < array.size(); ++i) {
if(array[i] % 2 == 1) {
odd.push_back(array[i]);
}
else {
even.push_back(array[i]);
}
}
result.insert(result.end(), odd.begin(), odd.end());
result.insert(result.end(), even.begin(), even.end());
return result;
}
int main(int argc, const char * argv[]) {
vector<int> array1{1, 2, 3, 4};
vector<int> array2{2, 4, 6, 5, 7};
vector<int> array3{1, 3, 5, 6, 7};
array1 = reOrderArray(array1);
array2 = reOrderArray(array2);
array3 = reOrderArray(array3);
return 0;
}
#include
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* FindKthToTail(ListNode* pHead, int k) {
// 检查非法输入
if(pHead == nullptr || k == 0) {
return nullptr;
}
ListNode* result = pHead;
for(int i = 0; i < k - 1; ++i) {
if(pHead->next != nullptr) {
pHead = pHead->next;
}
else {
return nullptr;
}
}
while(pHead->next != nullptr) {
result = result->next;
pHead = pHead->next;
}
return result;
}
int main(int argc, const char * argv[]) {
ListNode* a = new ListNode(1);
ListNode* b = new ListNode(2);
ListNode* c = new ListNode(3);
ListNode* d = new ListNode(4);
ListNode* e = new ListNode(5);
a->next = b;
b->next = c;
c->next = d;
d->next = e;
std::cout << FindKthToTail(a, 2)->val << std::endl;
return 0;
}
#include
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* EntryNodeOfLoop(ListNode* pHead) {
// 检查非法输入
if(pHead == nullptr) {
return nullptr;
}
const int MAX_VALUE = 10000;
int* visited = new int[MAX_VALUE + 1];
memset(visited, 0, (MAX_VALUE + 1)*sizeof(int));
while(pHead->next != nullptr) {
if(visited[pHead->val] == 1) {
return pHead;
}
else {
visited[pHead->val] = 1;
}
pHead = pHead->next;
}
return nullptr;
}
int main(int argc, const char * argv[]) {
ListNode* a = new ListNode(1);
ListNode* b = new ListNode(2);
ListNode* c = new ListNode(3);
ListNode* d = new ListNode(4);
ListNode* e = new ListNode(5);
a->next = b;
b->next = c;
c->next = d;
d->next = e;
e->next = c;
std::cout << EntryNodeOfLoop(a)->val << std::endl;
return 0;
}
#include
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* revertList(ListNode* pHead) {
// 检查非法输入
if(pHead == nullptr) {
return nullptr;
}
// 如果只有一个节点的话直接返回就可以了
if(pHead->next == nullptr) {
return pHead;
}
ListNode* now = pHead->next;
ListNode* pre = pHead;
ListNode* next;
pHead->next = nullptr;
while(now != nullptr) {
next = now->next;
now->next = pre;
pre = now;
now = next;
}
return pre;
}
int main(int argc, const char * argv[]) {
ListNode* a = new ListNode(1);
ListNode* b = new ListNode(2);
ListNode* c = new ListNode(3);
ListNode* d = new ListNode(4);
ListNode* e = new ListNode(5);
a->next = b;
b->next = c;
c->next = d;
d->next = e;
std::cout << revertList(a)->val << std::endl;
return 0;
}
#include
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* merge(ListNode* pHead1, ListNode* pHead2) {
// 检查非法输入
if(pHead1 == nullptr && pHead2 == nullptr) {
return nullptr;
}
// 初始化中间变量
ListNode* pHead;
ListNode* p;
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
// 确定头节点
if(pHead1 == nullptr) {
pHead = p2;
p2 = p2->next;
}
else if(pHead2 == nullptr){
pHead = p1;
p1 = p1->next;
}
else {
if(pHead1->val <= pHead2->val) {
pHead = p1;
p1 = p1->next;
}
else {
pHead = p2;
p2 = p2->next;
}
}
p = pHead;
while(p1 != nullptr && p2 != nullptr) {
if(p1->val <= p2->val) {
p->next = p1;
p1 = p1->next;
}
else {
p->next = p2;
p2 = p2->next;
}
p = p->next;
}
if(p1 != nullptr) {
p->next = p1;
p1 = p1->next;
p = p->next;
}
if(p2 != nullptr) {
p->next = p2;
p2 = p2->next;
p = p->next;
}
return pHead;
}
int main(int argc, const char * argv[]) {
ListNode* a = new ListNode(1);
ListNode* b = new ListNode(5);
ListNode* c = new ListNode(6);
ListNode* d = new ListNode(8);
ListNode* e = new ListNode(10);
a->next = b;
b->next = c;
c->next = d;
d->next = e;
ListNode* f = new ListNode(1);
ListNode* g = new ListNode(3);
ListNode* h = new ListNode(4);
ListNode* i = new ListNode(8);
ListNode* j = new ListNode(9);
f->next = g;
g->next = h;
h->next = i;
i->next = j;
ListNode* result1 = merge(a, f);
ListNode* result2 = merge(a, nullptr);
return 0;
}
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
// 递归的深度优先搜索,目的是判断两棵树是否一致
bool areSame(TreeNode* pRoot1, TreeNode* pRoot2) {
// 已经完全匹配上了
if(pRoot2 == nullptr) {
return true;
}
// 失败条件
if(pRoot1 == nullptr) {
return false;
}
// 判断
if(pRoot1->val == pRoot2->val) {
return areSame(pRoot1->left, pRoot2->left) && areSame(pRoot1->right, pRoot2->right);
}
else {
return false;
}
}
// 主搜索函数
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
// 判断非法输入
if(pRoot1 == nullptr || pRoot2 == nullptr) {
return false;
}
// 遍历待查找树
stack<TreeNode*> s;
s.push(pRoot1);
while(!s.empty()) {
// 出入栈以遍历树
TreeNode* now = s.top();
s.pop();
if(now->left != nullptr) {
s.push(now->left);
}
if(now->right != nullptr) {
s.push(now->right);
}
// 判断是否相同
if(areSame(now, pRoot2)) {
return true;
}
}
return false;
}
int main(int argc, const char * argv[]) {
TreeNode* a = new TreeNode(8);
TreeNode* b = new TreeNode(8);
TreeNode* c = new TreeNode(7);
TreeNode* d = new TreeNode(9);
TreeNode* e = new TreeNode(2);
TreeNode* f = new TreeNode(4);
TreeNode* g = new TreeNode(7);
a->left = b;
a->right = c;
b->left = d;
b->right = e;
e->left = f;
e->right = g;
TreeNode* A = new TreeNode(8);
TreeNode* B = new TreeNode(9);
TreeNode* C = new TreeNode(2);
A->left = B;
A->right = C;
TreeNode* E = new TreeNode(8);
TreeNode* F = new TreeNode(10);
TreeNode* G = new TreeNode(2);
E->left = F;
E->right = G;
TreeNode* H = new TreeNode(9);
TreeNode* I = new TreeNode(2);
H->left = I;
cout << (HasSubtree(a, A) == true) << endl;
cout << (HasSubtree(a, E) == false) << endl;
cout << (HasSubtree(a, H) == false) << endl;
return 0;
}
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
// 主搜索函数
TreeNode* Mirror(TreeNode* pRoot) {
// 判断非法输入
if(pRoot == nullptr) {
return nullptr;
}
// 遍历树,交换每个左右子树
stack<TreeNode*> s;
s.push(pRoot);
while(!s.empty()) {
// 出入栈以遍历树
TreeNode* now = s.top();
s.pop();
if(now->left != nullptr) {
s.push(now->left);
}
if(now->right != nullptr) {
s.push(now->right);
}
// 交换左右子树
TreeNode* temp;
temp = now->left;
now->left = now->right;
now->right = temp;
}
return pRoot;
}
int main(int argc, const char * argv[]) {
TreeNode* a = new TreeNode(8);
TreeNode* b = new TreeNode(8);
TreeNode* c = new TreeNode(7);
TreeNode* d = new TreeNode(9);
TreeNode* e = new TreeNode(2);
TreeNode* f = new TreeNode(4);
TreeNode* g = new TreeNode(7);
a->left = b;
a->right = c;
b->left = d;
b->right = e;
e->left = f;
e->right = g;
TreeNode* A = new TreeNode(8);
TreeNode* B = new TreeNode(9);
TreeNode* C = new TreeNode(2);
A->left = B;
A->right = C;
TreeNode* E = new TreeNode(8);
TreeNode* F = new TreeNode(10);
TreeNode* G = new TreeNode(2);
E->left = F;
E->right = G;
TreeNode* H = new TreeNode(9);
TreeNode* I = new TreeNode(2);
H->left = I;
cout << Mirror(a)->val << endl;
cout << Mirror(E)->val << endl;
cout << Mirror(H)->val << endl;
return 0;
}
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
bool isSymmetrical(TreeNode* pRoot) {
// 对一些特殊输入的判断
if(pRoot == nullptr) {
return true;
}
if(pRoot->left == nullptr && pRoot->right == nullptr) {
return true;
}
if(pRoot->left != nullptr && pRoot->right == nullptr) {
return false;
}
if(pRoot->left == nullptr && pRoot->right != nullptr) {
return false;
}
if(pRoot->left->val != pRoot->right->val) {
return false;
}
// 开始判断
stack<TreeNode*> ls;
stack<TreeNode*> rs;
ls.push(pRoot->left);
rs.push(pRoot->right);
while(!ls.empty() && !rs.empty()) {
TreeNode* ln = ls.top();
ls.pop();
TreeNode* rn = rs.top();
rs.pop();
if(ln->left == nullptr) {
if(rn->right == nullptr) {
// 相等,但是无需添加节点了
}
else {
// 不相等
return false;
}
}
else {
if(rn->right == nullptr) {
// 不相等
return false;
}
else {
if(ln->left->val == rn->right->val) {
// 相等,且要添加节点
ls.push(ln->left);
rs.push(rn->right);
}
else {
// 不相等
return false;
}
}
}
if(ln->right == nullptr) {
if(rn->left == nullptr) {
// 相等,但是无需添加节点了
}
else {
// 不相等
return false;
}
}
else {
if(rn->left == nullptr) {
// 不相等
return false;
}
else {
if(ln->right->val == rn->left->val) {
// 相等,且要添加节点
ls.push(ln->right);
rs.push(rn->left);
}
else {
// 不相等
return false;
}
}
}
}
if(ls.empty() && rs.empty()) {
return true;
}
else {
return false;
}
}
int main(int argc, const char * argv[]) {
TreeNode* a = new TreeNode(8);
TreeNode* b = new TreeNode(8);
TreeNode* c = new TreeNode(7);
TreeNode* d = new TreeNode(9);
TreeNode* e = new TreeNode(2);
TreeNode* f = new TreeNode(4);
TreeNode* g = new TreeNode(7);
a->left = b;
a->right = c;
b->left = d;
b->right = e;
e->left = f;
e->right = g;
TreeNode* A = new TreeNode(8);
TreeNode* B = new TreeNode(9);
TreeNode* C = new TreeNode(9);
A->left = B;
A->right = C;
TreeNode* E = new TreeNode(8);
TreeNode* F = new TreeNode(10);
TreeNode* G = new TreeNode(2);
E->left = F;
E->right = G;
TreeNode* H = new TreeNode(9);
TreeNode* I = new TreeNode(2);
H->left = I;
cout << isSymmetrical(a) << endl;
cout << isSymmetrical(A) << endl;
cout << isSymmetrical(E) << endl;
cout << isSymmetrical(H) << endl;
return 0;
}
#include
#include
using namespace std;
vector<int> printMatrix(vector<vector<int> > matrix) {
// 用来存储结果
vector<int> result;
// 检测非法输入
if(matrix.empty()) {
return result;
}
// 设置边界
int left = 0;
int right = matrix[0].size() - 1;
int bottom = 0;
int top = matrix.size() - 1;
// 设置方向(右-下-左-上)
int dir = 0;
// 计算总输出量
int num = matrix.size() * matrix[0].size();
// 开始输出
int x = 0, y = 0;
while(result.size() < num) {
// 向右走
if(dir == 0) {
// 检测是否遇到边界
if(y == right) {
dir = (dir + 1) % 4;
++bottom;
}
else {
result.push_back(matrix[x][y]);
++y;
}
}
// 向下走
else if(dir == 1){
// 检测是否遇到边界
if(x == top) {
dir = (dir + 1) % 4;
--right;
}
else {
result.push_back(matrix[x][y]);
++x;
}
}
// 向左走
else if(dir == 2) {
// 检测是否遇到边界
if(y == left) {
dir = (dir + 1) % 4;
--top;
}
else {
result.push_back(matrix[x][y]);
--y;
}
}
// 向上走
else {
// 检测是否遇到边界
if(x == bottom) {
dir = (dir + 1) % 4;
++left;
}
else {
result.push_back(matrix[x][y]);
--x;
}
}
}
return result;
}
int main(int argc, const char * argv[]) {
vector<vector<int>> matrix1{{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
printMatrix(matrix1);
vector<vector<int>> matrix2{{1},{2},{3},{4}};
printMatrix(matrix2);
return 0;
}
暂时先刷到这了,以后有空再刷…