diff --git "a/022-\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/README.md" "b/022-\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/README.md" index 36490de..3ed0dd8 100644 --- "a/022-\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/README.md" +++ "b/022-\346\240\210\347\232\204\345\216\213\345\205\245\345\274\271\345\207\272\345\272\217\345\210\227/README.md" @@ -90,50 +90,21 @@ using namespace std; class Solution { public: - bool IsPopOrder(vector pushV,vector popV) - { - - if(pushV.size( ) == 0 || popV.size( ) == 0) - { + bool IsPopOrder(vector pushV,vector popV) { + if(pushV.empty() || popV.empty() || pushV.size()!=popV.size()) return false; - } stack s; - int push, pop; - - s.push(pushV[0]); - debug <<"push" < -#include -#include -#include - -using namespace std; - -// 调试开关 -#define __tmain main - -#ifdef __tmain - -#define debug cout - -#else - -#define debug 0 && cout - -#endif // __tmain - - -class Solution -{ -protected: - vector m_res; - -public: - - vector Permutation(string str) - { - m_res.clear( ); - - if(str.empty( ) == true) - { - return m_res; - } - PermutationRecursion(str, 0); - - sort(m_res.begin( ), m_res.end( )); - return m_res; +vector Permutation(string str) { + vector v1; + if(str.size()<= 0 || str.size()>9 )//排除异常情况 + return v1; + PermutationHelp(v1, 0, str); + return v1; } - - - void PermutationRecursion(string str, int begin) - { - if(str[begin] == '\0') - { - debug <(cout," ")); - swap(str[i], str[begin]); - } - } - } - } - -private: - //find duplicate of str[i] in str[k,i) - bool HasDuplicate(string& str, int k, int i) const { - for (int p = k; p < i; p++) - if (str[p] == str[i]) return true; - - return false; - } -}; - -int __tmain( ) -{ - Solution solu; - solu.Permutation("abc"); - - return 0; -} + void PermutationHelp(vector &ans, int k, string str) //遍历第k位的所有可能 + { + if(k == (str.size() - 1))//单次递归终止条件 + ans.push_back(str); + unordered_set us;//保存字符串中字符的无序集合 + sort(str.begin() + k, str.end()); + for(int i = k; i < str.size(); i++) + { + if(us.find(str[i]) == us.end()) + { + us.insert(str[i]); + swap(str[i], str[k]); + PermutationHelp(ans, k + 1, str); + swap(str[i], str[k]); + } + } + } ``` #STL的next_permutation求全排列 @@ -263,4 +201,51 @@ public: } }; ``` +# 字符串的全组合 +```cpp +#include +#include +#include +#include +using namespace std; + +void Combination(char *string ,int number,vector &result); + +void Combination(char *string) +{ + assert(string != NULL); + vector result; + int i , length = strlen(string); + for(i = 1 ; i <= length ; ++i) + Combination(string , i ,result); +} +void Combination(char *string ,int number , vector &result) +{ + assert(string != NULL); + if(number == 0) + { + static int num = 1; + printf("第%d个组合\t",num++); + vector::iterator iter = result.begin(); + for( ; iter != result.end() ; ++iter) + printf("%c",*iter); + printf("\n"); + return ; + } + if(*string == '\0') + return ; + result.push_back(*string); + Combination(string + 1 , number - 1 , result); + result.pop_back(); + Combination(string + 1 , number , result); +} + +int main(void) +{ + char str[] = "abc"; + Combination(str); + return 0; +} + +``` diff --git "a/028-\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227/\345\255\227\347\254\246\344\270\262\347\232\204\345\205\250\347\273\204\345\220\210.cpp" "b/028-\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227/\345\255\227\347\254\246\344\270\262\347\232\204\345\205\250\347\273\204\345\220\210.cpp" new file mode 100644 index 0000000..df8752c --- /dev/null +++ "b/028-\345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227/\345\255\227\347\254\246\344\270\262\347\232\204\345\205\250\347\273\204\345\220\210.cpp" @@ -0,0 +1,38 @@ +void Combination(char *string ,int number,vector &result); + +void Combination(char *string) +{ + assert(string != NULL); + vector result; + int i , length = strlen(string); + for(i = 1 ; i <= length ; ++i) + Combination(string , i ,result); +} + +void Combination(char *string ,int number , vector &result) +{ + assert(string != NULL); + if(number == 0) + { + static int num = 1; + printf("第%d个组合\t",num++); + + vector::iterator iter = result.begin(); + for( ; iter != result.end() ; ++iter) + printf("%c",*iter); + printf("\n"); + return ; + } + if(*string == '\0') + return ; + result.push_back(*string); + Combination(string + 1 , number - 1 , result); + result.pop_back(); + Combination(string + 1 , number , result); +} +int main(void) +{ + char str[] = "abc"; + Combination(str); + return 0; +} diff --git "a/031-\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/README.md" "b/031-\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/README.md" index 3287ba5..785d77a 100644 --- "a/031-\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/README.md" +++ "b/031-\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\222\214/README.md" @@ -147,64 +147,22 @@ class Solution public: int FindGreatestSumOfSubArray(vector array) - { - - if(array.size( ) == 0) - { - return 0; - } - - - -#ifdef __tmain - - int temp, start, end; - -#endif // __tmain - - int maxSum = INT_MIN; - dp[0] = array[0]; - - for(unsigned int i = 1; i < array.size( ); i++) + { + if(array.size()<=0) + return -1; + int nsum_value = array[0]; //初始化f(i-1) + int max_sum = -1; + for(int i = 1; i < array.size(); i++) { - - if(dp[i - 1] <= 0) - { - dp[i] = array[i]; - -#ifdef __tmain - - temp = i; - -#endif // __tmain - - } + if(nsum_value <= 0) + nsum_value = array[i]; else - { - dp[i] = array[i] + dp[i - 1]; - } - - - if(dp[i] > maxSum) - { - maxSum = dp[i]; - -#ifdef __tmain - - start = temp; - end = i; - -#endif // __tmain - } - + nsum_value += array[i]; + + if(nsum_value > max_sum) + max_sum = nsum_value; } - - debug <<"[" <1,则个位上出现1的次数为(3014+1)*1 + 由于4>1,则十位上出现1的次数为(301+1)*10 + 由于1=1,则百位上出现1次数为(30+0)*100+(43+1) + 由于0<1,则千位上出现1次数为(3+0)*1000 + */ class Solution { public: @@ -379,37 +391,29 @@ public: */ int NumberOf1Between1AndN_Solution(int n) { - long count = 0; - - long i = 1; - - long current = 0,after = 0,before = 0; - - while((n / i) != 0) - { - before = n / (i * 10); - current = (n / i) % 10; - after = n - (n / i) * i; - if (current > 1) - { - count = count + (before + 1) * i; - } - else if (current == 0) - { - count = count + before * i; - } - else if(current == 1) - { - count = count + before * i + after + 1; - } - debug < numbers; - - for(int i = 0; i < n; i++) - { - numbers.push_back(i); - debug < 1) - { - debug <<"count = " <<1 <<", num[" <(cout, " ")); - debug <next = pHead; - - ListNode *p = pHead; - ListNode *last = first; - - while (p != NULL && p->next != NULL) + ListNode* firstNode = new ListNode(-1);//新建头结点 + firstNode->next = pHead; + ListNode* lastNode = firstNode; + ListNode* pNode = pHead; + + while(pNode != NULL && pNode->next != NULL) { - debug <val <val == p->next->val) + if(pNode->val == pNode->next->val) { - // 就跳过所有重复的数字 - int val = p->val; - while (p != NULL && p->val == val) - { - p = p->next; - } - - // 此时p指向了非重复的第一个元素 - // 我们设置last->next = p - // 但是此时p-val也可能是重复的, - // 因此我们不可以设置last = p - // 而是重新进入循环 - last->next = p; + int val = pNode->val; //保存重复的结点值 + ListNode* pToBeDel = pNode; + while( (pNode != NULL) && (pNode->val == val) ) + { + pNode = pToBeDel->next; //执行删除 + delete pToBeDel; + pToBeDel = nullptr; + pToBeDel = pNode; + } + lastNode->next = pNode; } - else + else { - last = p; - p = p->next; + lastNode = pNode; + pNode = pNode->next; } } - return first->next; + return firstNode->next; } }; @@ -194,4 +185,4 @@ public: } }; -``` \ No newline at end of file +``` diff --git "a/064-\346\225\260\346\215\256\346\265\201\344\271\213\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/README.md" "b/064-\346\225\260\346\215\256\346\265\201\344\271\213\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/README.md" index 439acd8..afe959f 100644 --- "a/064-\346\225\260\346\215\256\346\265\201\344\271\213\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/README.md" +++ "b/064-\346\225\260\346\215\256\346\265\201\344\271\213\344\270\255\347\232\204\344\270\255\344\275\215\346\225\260/README.md" @@ -30,17 +30,17 @@ ------- +``` +| 数据结构 | 插入的时间效率 | 得到的中位数的时间效率 | +|:-------: ||:-------: ||:-------:| +| 没有排序的数组 | O(1) | O(n) | +| 排序的数组 | O(n) | O(1) | +| 排序的链表 | O(n) | O(1) | +| 二叉搜索树 | 平均O(logn), 最差O(n) | 平均O(logn), 最差O(n) | +| AVL树 | O(logn) | O(1) | +| 最大堆和最小堆 | O(logn) | O(1) | -| 数据结构 | 插入的时间效率 | 得到的中位数的时间效率 | -|:-------:||:-------:||:-------:| -| 没有排序的数组 | O(1) | O(n) | -| 排序的数组 | O(n) | O(1) | -| 排序的链表 | O(n) | O(1) | -| 二叉搜索树 | 平均O(logn), 最差O(n) | 平均O(logn), 最差O(n) | -| AVL树 | O(logn) | O(1) | -| 最大堆和最小堆 | O(logn) | O(1) | - - +``` @@ -247,4 +247,4 @@ public : } }; ``` - \ No newline at end of file + diff --git "a/066 \346\225\260\345\255\227\345\272\217\345\210\227\344\270\255\346\237\220\344\270\200\344\275\215\347\232\204\346\225\260\345\255\227" "b/066 \346\225\260\345\255\227\345\272\217\345\210\227\344\270\255\346\237\220\344\270\200\344\275\215\347\232\204\346\225\260\345\255\227" new file mode 100644 index 0000000..4fe0757 --- /dev/null +++ "b/066 \346\225\260\345\255\227\345\272\217\345\210\227\344\270\255\346\237\220\344\270\200\344\275\215\347\232\204\346\225\260\345\255\227" @@ -0,0 +1,95 @@ +**题目描述** + +题目描述 + +>数字以01234567891011121314...的格式化系列化到一个字符串中,在这个序列中, 第5位(从0开始计数)是5,第13位是1, 第19位是4,等等。请写一个函数, +求任意第n位对应的数字。 + +比如:序列中的二弟1001位是什么? + 首先,序列的前10位是0~9着10个只有一位的数字。显然,第100位在这10个数字之后,因此,可直接跳过这10个数字。然后在从后面紧跟的序列中找地991 +(1001-10)位的数字。 + 接下来180位数字中有90个10~99的两位数,由于991 > 180,所以991在所有的两位数之后。在跳过90个两位数,继续向后找881(811= 991 -180)位; + 接下来的2700位是900个100~999的三位数,由于811 < 2700,所以881是某一三位数的一位。因为811/3 = 270,且811%3 = 1。这意味着811是从100开始 +的第270个数字即370的中间一位,也就是7. +``` +#include +#include +using namespace std; + +//取得位数为index的数开头的第一个数 +int getFst(int index) +{ + if (index == 1)return 0; + + return static_cast(pow(10, index - 1)); +} + +//最后取得指定位上的数字 +int getTheNum(int num, int posi, int index) +{ + int n = index - posi - 1; + + for (int i = 0; i < n; i++) { + num = num / 10; + } + + return num % 10; +} + +//位数为n的数一共有多少个 +int cntOfIntegers(int n) +{ + if (n == 1)return 10; + + int resu = 1; + for (int i = 1; i != n; i++) { + resu *= 10; + } + + return 9 * resu; +} + +//位数为n的数一共有多少个 +int cntOfIntegers1(int n) +{ + if (n == 1)return 10; + return 9 * static_cast(pow(10, n - 1)); +} + +int numOnPosiN(int n) +{ + //输入出错的情况 + if (n < 0)return -1; + + int index = 1; + while (true) { + //cnt为位数为index的数一共所占的位数 + int cnt = cntOfIntegers(index)*index; + if (n - cnt < 0) { + // + int fst = getFst(index); + int pre = n / index;//从fst开始的第pre个index位数 例:811/3=270==>即为从100开始的第270个数,即370() + int remain = n % index;//从fst开始的第pre个index位数的第remain位 例:811%3==》即为370的从0开始计算的第remain+1为数 + + return getTheNum(fst + pre, remain, index); + } + + n -= cnt; + index++; + } + + //如果循环完毕还没有返回,说明出错返回-1 + return -1; +} + +int main() +{ + cout << "Please enter a interger:" << endl; + int n; + while (cin >> n) { + cout << numOnPosiN(n) << endl; + } + system("pause"); + return 0; +} +``` diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..4c96dd8 --- /dev/null +++ b/README.MD @@ -0,0 +1,179 @@ + +#include +#include +#include +#include +using namespace std; + +//判断是否为操作符 +bool isOperator(char op) +{ + return (op == '+' || op == '-' || op == '*' || op == '/'); +} + +//判断是否为数字 +bool isDigit(char op) +{ + return (op >= '0' && op <= '9'); +} + +//计算表达式结果 +int cal(int left, int right, char op) +{ + int res = 0; + if (op == '+') + res = left + right; + else if (op == '-') + res = left - right; + else if (op == '*') + res = left * right; + else if (op == '/') + res = left / right; + return res; +} + +//判断运算符优先级 +int pirority(char op) +{ + if (op == '+' || op == '-') + return 1; + if (op == '*' || op == '/') + return 2; + else + return 0; +} + +//逆波兰表达式转中缀表达式 +int evalRPN(string &tokens) +{ + if (tokens.size() <= 0) + return 0; + stack s1;//创建辅助栈 + int left = 0, right = 0;//定义左/右操作数 + int result = 0;//定义中间结果 + string temp; + for (unsigned int i = 0; i < tokens.size(); i++ ) + { + + if (isDigit(tokens[i]))//扫描数字入栈 + { + temp.push_back(tokens[i]); + } + else if (tokens[i] == ' ') + { + if (temp.size() > 0) //防止运算符后面跟分隔符,所以判断一下temp里面是否有数字 + { + s1.push(atoi(temp.c_str())); + temp.clear(); + } + } + else if (isOperator(tokens[i]) && !s1.empty()) + { + //防止数字后面直接跟运算符,所以这里也要判断一下temp是否还有数字没有提取出来 + if (temp.size() > 0) + { + s1.push(atoi(temp.c_str())); + temp.clear(); + } + right = s1.top(); + s1.pop(); + + left = s1.top(); + s1.pop(); + + result = cal(left, right, tokens[i]); + s1.push(result); + } + + } + if (!s1.empty()) + { + result = s1.top(); + s1.pop(); + } + + return result; +} + + + + +//中缀表达式转逆波兰表达式 +vector infixToPRN(const string & token) +{ + vector v1; + int len = token.size();//string的长度 + if (len == 0) + return v1; + + stack s1;//存放逆波兰式的结果 + int outLen = 0; + for (int i = 0; i < len ; i++) + { + if (token[i] == ' ')//跳过空格 + continue; + if (isDigit(token[i]) )//若是数字,直接输出 + { + v1.push_back(token[i]); + } + else if (token[i] == '(')//如果是'(',则压栈 + { + s1.push(token[i]); + }else if (token[i] == ')')//如果是')', 则栈中运算符逐个出栈并输出,直至遇到'('。 '('出栈并丢弃 + { + while (s1.top() != '(') + { + v1.push_back( s1.top()); + s1.pop(); + } + s1.pop();//此时栈中为')',跳过 + } + while (isOperator(token[i]))//如果是运算符 + { + //空栈||或者栈顶为)||新来的元素优先级更高 + if( s1.empty() || s1.top() == '(' || pirority(token[i]) > pirority(s1.top())) + { + s1.push(token[i]);// 当前操作符优先级比栈顶高, 将栈顶操作符写入后缀表达式 + break; + }else + { + v1.push_back(s1.top()); + s1.pop(); + } + + + } + } + while (!s1.empty())//输入结束,将栈中剩余操作符出栈输出 + { + v1.push_back(s1.top()); + s1.pop(); + } + return v1; +} +int main() +{ + //vector sRPN = {"4", "13", "5" , "/", "+"};//逆波兰表达式 + //cout << "逆波兰表达式结果为:" << evalRPN(sRPN) < fix = {"4", "+", "13", "/", "5"};//中缀表达式 + string fix = "2+2*(1*2-4/2)*1"; + vector RPN = infixToPRN(fix); + string s_fix; + for (auto it = RPN.begin(); it != RPN.end(); it++) + { + cout << *it << " "; + s_fix += *it; + s_fix += " "; + } + cout << endl; + cout << "逆波兰表达式结果为:" << evalRPN(s_fix) << endl; + + + + system("pause"); + + return 0; + +} + diff --git "a/\344\270\255\347\274\200\350\241\250\350\276\276\345\274\217\343\200\212==\343\200\213\345\220\216\347\274\200\350\241\250\350\276\276\345\274\217.cpp" "b/\344\270\255\347\274\200\350\241\250\350\276\276\345\274\217\343\200\212==\343\200\213\345\220\216\347\274\200\350\241\250\350\276\276\345\274\217.cpp" new file mode 100644 index 0000000..4c96dd8 --- /dev/null +++ "b/\344\270\255\347\274\200\350\241\250\350\276\276\345\274\217\343\200\212==\343\200\213\345\220\216\347\274\200\350\241\250\350\276\276\345\274\217.cpp" @@ -0,0 +1,179 @@ + +#include +#include +#include +#include +using namespace std; + +//判断是否为操作符 +bool isOperator(char op) +{ + return (op == '+' || op == '-' || op == '*' || op == '/'); +} + +//判断是否为数字 +bool isDigit(char op) +{ + return (op >= '0' && op <= '9'); +} + +//计算表达式结果 +int cal(int left, int right, char op) +{ + int res = 0; + if (op == '+') + res = left + right; + else if (op == '-') + res = left - right; + else if (op == '*') + res = left * right; + else if (op == '/') + res = left / right; + return res; +} + +//判断运算符优先级 +int pirority(char op) +{ + if (op == '+' || op == '-') + return 1; + if (op == '*' || op == '/') + return 2; + else + return 0; +} + +//逆波兰表达式转中缀表达式 +int evalRPN(string &tokens) +{ + if (tokens.size() <= 0) + return 0; + stack s1;//创建辅助栈 + int left = 0, right = 0;//定义左/右操作数 + int result = 0;//定义中间结果 + string temp; + for (unsigned int i = 0; i < tokens.size(); i++ ) + { + + if (isDigit(tokens[i]))//扫描数字入栈 + { + temp.push_back(tokens[i]); + } + else if (tokens[i] == ' ') + { + if (temp.size() > 0) //防止运算符后面跟分隔符,所以判断一下temp里面是否有数字 + { + s1.push(atoi(temp.c_str())); + temp.clear(); + } + } + else if (isOperator(tokens[i]) && !s1.empty()) + { + //防止数字后面直接跟运算符,所以这里也要判断一下temp是否还有数字没有提取出来 + if (temp.size() > 0) + { + s1.push(atoi(temp.c_str())); + temp.clear(); + } + right = s1.top(); + s1.pop(); + + left = s1.top(); + s1.pop(); + + result = cal(left, right, tokens[i]); + s1.push(result); + } + + } + if (!s1.empty()) + { + result = s1.top(); + s1.pop(); + } + + return result; +} + + + + +//中缀表达式转逆波兰表达式 +vector infixToPRN(const string & token) +{ + vector v1; + int len = token.size();//string的长度 + if (len == 0) + return v1; + + stack s1;//存放逆波兰式的结果 + int outLen = 0; + for (int i = 0; i < len ; i++) + { + if (token[i] == ' ')//跳过空格 + continue; + if (isDigit(token[i]) )//若是数字,直接输出 + { + v1.push_back(token[i]); + } + else if (token[i] == '(')//如果是'(',则压栈 + { + s1.push(token[i]); + }else if (token[i] == ')')//如果是')', 则栈中运算符逐个出栈并输出,直至遇到'('。 '('出栈并丢弃 + { + while (s1.top() != '(') + { + v1.push_back( s1.top()); + s1.pop(); + } + s1.pop();//此时栈中为')',跳过 + } + while (isOperator(token[i]))//如果是运算符 + { + //空栈||或者栈顶为)||新来的元素优先级更高 + if( s1.empty() || s1.top() == '(' || pirority(token[i]) > pirority(s1.top())) + { + s1.push(token[i]);// 当前操作符优先级比栈顶高, 将栈顶操作符写入后缀表达式 + break; + }else + { + v1.push_back(s1.top()); + s1.pop(); + } + + + } + } + while (!s1.empty())//输入结束,将栈中剩余操作符出栈输出 + { + v1.push_back(s1.top()); + s1.pop(); + } + return v1; +} +int main() +{ + //vector sRPN = {"4", "13", "5" , "/", "+"};//逆波兰表达式 + //cout << "逆波兰表达式结果为:" << evalRPN(sRPN) < fix = {"4", "+", "13", "/", "5"};//中缀表达式 + string fix = "2+2*(1*2-4/2)*1"; + vector RPN = infixToPRN(fix); + string s_fix; + for (auto it = RPN.begin(); it != RPN.end(); it++) + { + cout << *it << " "; + s_fix += *it; + s_fix += " "; + } + cout << endl; + cout << "逆波兰表达式结果为:" << evalRPN(s_fix) << endl; + + + + system("pause"); + + return 0; + +} +