diff --git a/BinarySearch.cpp b/BinarySearch.cpp index bd6d9f6..448288b 100644 --- a/BinarySearch.cpp +++ b/BinarySearch.cpp @@ -1,8 +1,10 @@ +#include + int BinarySearch(int array[], int n, int value){ int left = 0; int right = n - 1; - while(left <= right){ + while(left <= right){//注意此处的边界为什么要等于?只有一个元素的时候 int middle = left + ((right - left) >> 1);//>> 1(二进制右移动一位相当于/2) 或者(right-left) / 2 + left 不会溢出 if(array[middle] > value) right = middle - 1; @@ -17,17 +19,17 @@ int BinarySearch(int array[], int n, int value){ //递归写法 int BinarySearch2(int array[], int start, int end, int key){ - int middle = (right - left) >> 1 + left; + int middle = (end - start) >> 1 + start; if(middle == key) return middle; if(end <= start){ return -1 } else if(key > middle){ - return BinarySearch2(array[], middle + 1, end); + return BinarySearch2(array[], middle + 1, end, key); } else if(key < middle){ - return BinarySearch2(array[], start, middle - 1); + return BinarySearch2(array[], start, middle - 1, key); } return -1; } diff --git a/a.out b/a.out index 60b07c2..9b5a397 100755 Binary files a/a.out and b/a.out differ diff --git a/binarySearch.cpp b/binarySearch.cpp new file mode 100644 index 0000000..ef506f7 --- /dev/null +++ b/binarySearch.cpp @@ -0,0 +1,34 @@ +include + +using namespace std; +//边界为【L, R】 +int binarySearch(int array[], int n, int target){ + int l = 0; + int r = n - 1; + int middle = (r - l) / 2 + l; + while(l <= r){ + if(target > array[middle] ) + l = middle + 1; + else if(target < array[middle]) + r = middle - 1; + else return array[middle]; + } + return -1; +} + + + +//边界为[L, R) +int binarySearch2(int array[], int n, int target){ + int l = 0; + int r = n; + int middle = l + (r - l) >> 1 + while(l < r){ + if(target > array[middle]) + l = middle + 1; + else if(target < array[middle]) + r = middle; + else return array[middle]; + } + return -1; +} diff --git a/dynamic programming/digGlod.md b/dynamic programming/digGlod.md new file mode 100644 index 0000000..e69de29 diff --git a/dynamic programming/package.md b/dynamic programming/package.md new file mode 100644 index 0000000..705fa92 --- /dev/null +++ b/dynamic programming/package.md @@ -0,0 +1,23 @@ +#### 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。 +背包容积为10,5种物品, +价值->重量 +8 6 +7 4 +4 2 +5 4 +5 3 +```c +#include "stdio.h" +define max(a,b) ((a)>(b)?(a):(b)) + +main(){ + int v = 10; + int n = 5; + + int value[] = {0, 8, 7, 4, 5, 5}; + int weight[] = {0, 6, 4, 2, 4, 3}; + + int i, j; + int dp[][]; +} +``` diff --git "a/dynamic programming/\346\226\220\346\263\242\346\213\211\345\210\207\346\225\260\345\210\227.md" "b/dynamic programming/\346\226\220\346\263\242\346\213\211\345\210\207\346\225\260\345\210\227.md" new file mode 100644 index 0000000..c5653d1 --- /dev/null +++ "b/dynamic programming/\346\226\220\346\263\242\346\213\211\345\210\207\346\225\260\345\210\227.md" @@ -0,0 +1,23 @@ +#### 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 +***动态规划*** + +```c +class Solution{ +public: + int Fibonacci(int n){ + if(n == 0) + return 0; + if(n == 1 || n == 2) + return 1; + int i, a = 1, b = 1, result; + for(int i = 3; i < n; i++){ + result = a + b; + a = b; + b = result; + } + return result; + } +} +``` +Fibonacci如果用递归虽然代码简单但是计算量会指数型增长 +Fibonacci数列和跳台阶都可以用动态规划 diff --git "a/dynamic programming/\346\234\200\345\244\247\350\277\236\347\273\255\345\255\220\345\272\217\345\210\227\344\271\213\345\222\214.md" "b/dynamic programming/\346\234\200\345\244\247\350\277\236\347\273\255\345\255\220\345\272\217\345\210\227\344\271\213\345\222\214.md" new file mode 100644 index 0000000..68ff0a7 --- /dev/null +++ "b/dynamic programming/\346\234\200\345\244\247\350\277\236\347\273\255\345\255\220\345\272\217\345\210\227\344\271\213\345\222\214.md" @@ -0,0 +1,47 @@ +#### 求取数组中最大连续子序列和,例如给定数组为A={1, 3, -2, 4, -5}, 则最大连续子序列和为6,即1+3+(-2)+ 4 = 6。 +***o(N^2)*** +```c +int maxsequnence(int arr[], int len) +{ + int max = 0; + for(int i = 0; i < len; i++) + { + sum = 0; + for(int j = i; j < len; j++) + { + sum += arr[j]; + if(max < sum) + max = sum; + } + } + return max; +} +``` + +***o(N)*** +因为最大 连续子序列和只可能是以位置0~n-1中某个位置结尾。当遍历到第i个元素时,判断在它前面的连续子序列和是否大于0,如果大于0,则以位置i结尾的最大连续子序列和为元素i和前门的连续子序列和相加;否则,则以位置i结尾的最大连续子序列和为元素i。 +```c +maxsequnence2(int a[], int len) +{ + int maxsum , maxhere; + maxsum = maxhere = arr[0]; + + for(int i = 1; i < len; i++) + { + maxhere = arr[i]; + if(maxhere < 0) + { + maxsum = arr[i]; + } + else + { + maxhere += arrr[i]; + if(maxhere > maxsum) + { + maxsum = maxhere; + } + } + } + return maxsum; +} +``` diff --git "a/dynamic programming/\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227(LCS).md" "b/dynamic programming/\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227(LCS).md" new file mode 100644 index 0000000..e69de29 diff --git "a/dynamic programming/\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227(LIS).md" "b/dynamic programming/\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227(LIS).md" new file mode 100644 index 0000000..4d41212 --- /dev/null +++ "b/dynamic programming/\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227(LIS).md" @@ -0,0 +1,23 @@ +设f(i)表示L中以ai为末元素的最长递增子序列的长度。则有如下的递推方程: + +这个递推方程的意思是,在求以ai为末元素的最长递增子序列时,找到所有序号在L前面且小于ai的元素aj,即j f[i]-1) + { + f[i] = f[j] + 1; + } + } + } + +} +``` diff --git "a/dynamic programming/\350\267\263\351\235\222\350\233\231.md" "b/dynamic programming/\350\267\263\351\235\222\350\233\231.md" new file mode 100644 index 0000000..306e12a --- /dev/null +++ "b/dynamic programming/\350\267\263\351\235\222\350\233\231.md" @@ -0,0 +1,21 @@ +#### 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。 +```c +class Solution{ +public: + int jumpFloor(int number){ + if(number == 0) + return false; + if(number == 1 || number == 2) + return number; + else{ + int result, a = 1, b = 2, i; + for(i = 3; i <= number; i++){ + result = a + b; + a = b; + b = result; + } + return result; + } + } +} +``` diff --git "a/dynamic programming/\350\267\263\351\235\222\350\233\231\345\217\230\346\200\201.md" "b/dynamic programming/\350\267\263\351\235\222\350\233\231\345\217\230\346\200\201.md" new file mode 100644 index 0000000..93c558e --- /dev/null +++ "b/dynamic programming/\350\267\263\351\235\222\350\233\231\345\217\230\346\200\201.md" @@ -0,0 +1,22 @@ +#### 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 +```c +class Solution{ +public: + intjumpFloorll(int number){ + if(number == 0) + return false; + if(number == 1) + return 1; + else{ + int i, reslut; a = 1; + for(i = 2; i <= number; i++){ + result = 2 * a; + a = result; + } + return reslut; + } + } +}; + +``` + diff --git a/eight_Queen.cpp b/eight_Queen.cpp new file mode 100644 index 0000000..f374662 --- /dev/null +++ b/eight_Queen.cpp @@ -0,0 +1,158 @@ +#include +#include + +static final int MAX_NUM = 8; +int chessBoard[][] = new int[MAX_NUM][MAX_NUM]; + +//判断落点是否符合规范 +boolean check(int x, int y) +{ + for(int i = 0; i < y; i++) + { + //检查纵向 + if(chessBoard[x][i] == 1) + { + return false; + } + + //检查左侧倾斜 x-1,y-1就是x,y的左斜上方一个 + if(x-1-i >= 0 && chessBoard[x-1-i][y-1-i] == 1) + { + return false; + } + + //检查左侧倾斜 x+1,y+1就是x,y的右斜上方一个 + if(x+1+i >= 0 && chessBoard[x+1+i][y+1+i] == 1) + { + return false; + } + } + return true; +} + + +//递归回溯 +boolean settleQueen(int y){ + //行数超过最大则已经找出答案 + if(y == MAX_NUM){ + return true; + } + + //遍历当前行,逐一格子验证 + for(int i = 0; i < MAX_NUM; i++) + { + //把当前行全部置0,防止回溯的时候有脏数据 + for(int j = 0; j < MAX_NUM; j++) + { + chessBoard[i][j] == 0; + } + //检查落点是否符合,如果符合将落点置为1,并且继续下一轮递归 + if(check(i,y)) + { + chessBoard[i][y] == 1; + //如果下一层返回true那么就已经找到解法,无需再循环 + if(settleQueen[y+1]) + { + return true; + } + } + } + return false; +} + + +//打印结果 +void printChessBoard() +{ + for(int i = 0; i < MAX_NUM; i++) + { + for(int j = 0; j < MAX_NUM; j++) + { + cout<=0&&j>=0) +// { +// if(m[i][j]==1) return false; +// i--; +// j--; +// } +// //右上至左下只能有一枚皇后 +// i = row-2; +// j = row+column-i-2; +// while(i>=0&&j<=7) +// { +// if(m[i][j]==1) return false; +// i--; +// j++; +// } +// return true; +// } +// +// //当已放置8枚皇后,为可行解时,输出棋盘 +// void output() +// { +// int i,j; +// num++; +// printf("answer %d:\n",num); +// for(i=0;i<8;i++) +// { +// for(j=0;j<8;j++) printf("%d ",m[i][j]); +// printf("\n"); +// } +// } +// +// //采用递归函数实现八皇后回溯算法 +// //该函数求解当棋盘前row-1行已放置好皇后,在第row行放置皇后 +// void solve(int row) +// { +// int j; +// //考虑在第row行的各列放置皇后 +// for (j=0;j<8;j++) +// { +// //在其中一列放置皇后 +// m[row-1][j] = 1; +// //检查在该列放置皇后是否可行 +// if (check(row,j+1)==true) +// { +// //若该列可放置皇后,且该列为最后一列,则找到一可行解,输出 +// if(row==8) output(); +// //若该列可放置皇后,则向下一行,继续搜索、求解 +// else solve(row+1); +// } +// //取出该列的皇后,进行回溯,在其他列放置皇后 +// m[row-1][j] = 0; +// } +// } +// +// //主函数 +// int main() +// { +// //求解八皇后问题 +// solve(1); +// return 0; +// } diff --git a/get_dir.php b/get_dir.php new file mode 100644 index 0000000..a866e0a --- /dev/null +++ b/get_dir.php @@ -0,0 +1,21 @@ + 0; --i) { - //最后一个元素和第一个元素进行比较 + //最后一个元素和第一个元素进行交换 就是将大的元素放到数组后面然后继续调整为最大堆 ElemType temp = A[i]; A[i] = A[0]; A[0] = temp; diff --git a/insert_Sort.cpp b/insert_Sort.cpp index e8b6214..03c56a8 100644 --- a/insert_Sort.cpp +++ b/insert_Sort.cpp @@ -8,7 +8,6 @@ void InsertSort(int array[], int n) int temp = array[i]; for (j = i - 1; j >= 0 && array[j] > temp; j--){ array[j + 1] = array[j]; - } cout<<"*"< +#include + + +using namespace std; + +class Solution{ + public: + void moveZeroes(vector & nums){ + vector nonZeroElements; + for(int i = 0; i < nums.size(); i++){ + if(nums[i]) + nonZeroElements.push_back(nums[i]); + } + for(int i = 0; i < nums.size(); i++){ + nums[i] = nonZeroElements[i]; + } + + for(int i = nonZeroElements.size(); i < nums.size(); i++){ + nums[i] = 0; + } + + } + } +} + + +//不使用额外的空间 +void moveZeroes(vector& nums){ + int k = 0; + int i = 0; + for(; i < nums.size(); i++){ + if(nums[i]) + if(i != k)//如果全部是非0元素,那么就不需要自身和自身交换了 + swap(nums[k++], nums[i]); + else + k++; + } +} diff --git a/offer/18.md b/offer/18.md index e69de29..d397dcf 100644 --- a/offer/18.md +++ b/offer/18.md @@ -0,0 +1,44 @@ +#### 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的) + +***1.我开始的想法*** +```c +class Solution { +public: + bool IsPopOrder(vector pushV,vector popV) { + + vector tempV; + for(int i = 0; i < popV.size(); i++){ + tempV.push_back(popV[i]); + } + for(int j = 0; j < pushV.size(); j++){ + if(pushV[j] != tempV[j]) + return false; + } + return true; + } +}; +``` +没有考虑到中途的操作,比如中途先弹出4,再压入5,最后的打印顺序是45321 + +***2.正确的思路*** +入:12345,出45321.借助一个辅助栈,先将入栈序列压入辅助栈,判断栈顶元素是否和出栈元素相等,如果相等,辅助栈出栈,出栈向上移。继续入栈,判断相等,出栈,上移操作。最后辅助栈为空,那么返回true。else 返回false +```c +class Solution{ +public: + bool IsPopOrder(vector pushV, vector popV){ + stack temp;//辅助栈 + + int length = pushV.size(); + int popIndex = 0; + + for(int i = 0; i < length; i++){ + temp.push(pushV[i]); + while(!temp.empty() && temp.top() == popV[popIndex]){ + popIndex++; + temp.pop(); + }//否则继续进栈 + } + return temp.empty();//如果最后temp为空那麽就是正确的弹出序列 + } +} +``` diff --git a/offer/20.md b/offer/20.md index e69de29..b4b3cea 100644 --- a/offer/20.md +++ b/offer/20.md @@ -0,0 +1,5 @@ +#### 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果 +***什么是二叉搜索树(二叉排序树)*** +(1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值; +(2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值; +(3)左、右子树也分别为二叉排序树; diff --git a/offer/21.md b/offer/21.md new file mode 100644 index 0000000..0abc781 --- /dev/null +++ b/offer/21.md @@ -0,0 +1,33 @@ +#### 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 +***回溯法*** +代码尚未通过 +```c +class Solution { +public: + vector Permutation(string str) { + vector array; + if(str.size() == 0) + return array; + permutation_helper( str, array, 0); + return array; + } + + private: + void permutation_helper(vector str, vector array, int begin ){ + if(begin >= str.size()) + { + array.push_back(str); + + } + + for(int i = begin; i < str.size(); i++) + { + swap(str[begin], str[i]); + permutation(str, array, begin + 1); + swap(str[begin], str[i]); + } + } +}; +``` + +回溯法就是隐含的深度优先搜索,类似的问题还有八皇后的问题。使用递归实现回溯。 diff --git a/quick_Sort.cpp b/quick_Sort.cpp index 1c1138a..eb30e04 100644 --- a/quick_Sort.cpp +++ b/quick_Sort.cpp @@ -2,6 +2,7 @@ using namespace std; //快速排序 +//快排也是采用分治法 static void swap(int *a, int *b)//a,b都是地址 { int tmp; @@ -10,23 +11,25 @@ static void swap(int *a, int *b)//a,b都是地址 *b = tmp; } -static int partition(int arr[], int left, int right) +static int partition(int arr[], int left, int right)//将大于基数的放在基数右边,将小于基数的放在基数左边 { int i = left; int j = right; - int pivot = arr[left]; + int pivot = arr[left];//将左边的选为基数 while(i < j){ + while(i < j && arr[j] >= pivot){ - --j; + j--; } while(i < j && arr[i] <= pivot){ - ++i; - }//当i=j后 i还向前多移动一位 + i++; + } if(i < j){ swap(&arr[i], &arr[j]);//&符号取地址 } + } swap(&arr[left], &arr[i]); return i;//返回下标 @@ -35,12 +38,12 @@ static int partition(int arr[], int left, int right) static void quick_sort(int arr[], int left, int right) { - int pivot_pos; + int pivot_pos;//将数组分开处的下标 if(left < right){ pivot_pos = partition(arr, left, right);//交换后的下标 - quick_sort(arr, left, pivot_pos - 1);//前面的i多向前跑了一位 - quick_sort(arr, pivot_pos + 1, right);//原本是从pivot_pos开始,但是上面-1了,下面就要+1 + quick_sort(arr, left, pivot_pos); + quick_sort(arr, pivot_pos + 1, right); } } diff --git a/shell_Sort.cpp b/shell_Sort.cpp index 50070e5..c3f3221 100644 --- a/shell_Sort.cpp +++ b/shell_Sort.cpp @@ -16,6 +16,21 @@ void Shell_sort(int *arr, int n) } } +//错误原因:我用 tmp = i 后面的中间变量用array[tmp],这根本就没有成为中间量!! +// void Shell_sort(int *array, int n){ +// int i, j, gap; +// int tmp; +// for(gap = n / 2; gap > 0; gap /= 2){ +// for(i = gap; i < n; ++i){ +// tmp = i; +// for(j = i - gap; j >= 0 && array[j] > array[tmp]; j -= gap){ +// array[j + gap] = array[j]; +// } +// array[j + gap] = array[tmp]; +// } +// } +// } + int main() { int data[]={5,1,19,22,3,1,23,6}; //输入待排序数组 @@ -24,4 +39,5 @@ int main() cout<>>>>>> iss55 diff --git "a/\345\215\201\344\270\252\346\216\222\345\272\217\347\256\227\346\263\225.cpp" "b/\345\215\201\344\270\252\346\216\222\345\272\217\347\256\227\346\263\225.cpp" new file mode 100644 index 0000000..af4b13b --- /dev/null +++ "b/\345\215\201\344\270\252\346\216\222\345\272\217\347\256\227\346\263\225.cpp" @@ -0,0 +1,213 @@ +//1.冒泡排序 +//两两比较放到最后,每一趟都会选出一个最大或者最小 +//O(n^2) +void bubbleSort(int array[], int n) +{ + for(int i = 0; i < n - 1; i++){//i是比较的次数,一共要比较n-1次,这里的i从0开始,所以要 array[j + 1]) + swap(array[j], array[j + 1]); + } + } +} +//冒泡优化 设置标志变量 +function bubbleSort2(int array[], int n) +{ + int i, j, change = 0; + + for(i = 0; i < n - 1 && change != 0; i++){//如果没有交换(change=0)就终止循环 + change = 0;//在n-1次比较中,只要有一次没有交换就有序了 + for(j = 0; j < n - 1 - i; j++){ + if(array[j] > array[j + 1]){ + swap(array[j] > array[j++]); + change = 1;//表示有交换 + } + } + } +} +******************************************************************************** +//2.选择排序 +//从后面的选出最小的放到前面 +//O(n^2) +void selectionSort(int array[], int n) +{ + int minIndex = 0; + + for(int i = 0; i < n - 1; i++){ + minIndex = i; + for(int j = i + 1; j < n; j++){ + if(array[j] < array[minIndex]){ + minIndex = j; + } + } + swap(array[minIndex], array[i]); + } +} +******************************************************************************** +//插入排序 +//把后面的按大小插入到前面 +//O(n^2) +void insertSort(int array[], int n) +{ + int i, j, tmp; + + for(int i = 1; i < n; i++){ + tmp = array[i]; + for(int j = i - 1; j >= 0; j--){ + if(array[j] > tmp) + { + array[j + 1] = array[j]; + }else{ + break; + } + } + array[j + 1] = tmp;// 到-1时终止循环,所以要加一 + } +} + +//插入排序 +void insertSort(int array[], int n){ + for(int i = 0; i < n; i++){ + int tmp = array[i]; + for(int j = i -1; j >= 0 && array[j] > tmp; j--){ + array[j + 1] = array[j];//将大的数向前移动 + } + array[j + 1] = tmp;//将小的数插入到空位中 + } +} + +******************************************************************************** +//希尔排序 +//基于插入排序,平均O(n^1.3) +void shellSort(int *array, int n){ + int i, j, gap; + for(gap = n / 2; gap > 0; gap /= 2){ + for(int i = gap; i < n; i++){ + int tmp = array[i]; + for(int j = i + gap; j >= 0 && array[j] > tmp; j -= gap){ + array[j + gap] = array[j]; + } + array[j + gap] = tmp; + } + } +} + +******************************************************************************** +//归并排序 +//用到分治法的思想,将数组不断的分下去,分到最后只剩下一个元素就是有序的了,再来合并成有序的数组 +//分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题, +//然后将这些子问题的解组合为原问题的解。 +//O(nlogn) +void merge(int arr[], int L, int M, int R){ + int LEFT_SIZE = M - L + 1; + int RIGHT_SIZE = R - M; + int left[LEFT_SIZE]; + int right[RIGHT_SIZE]; + + for(int i = L; i <= M; i++){//拆分的时候M是包含在右边的 + left[i - L] = arr[i]; + } + + for(int i = M + 1; i <= R; i++){ + right[i - M - 1] = arr[i]; + } + + //将两个数组合并为一个有序的数组 + i = 0; j = 0; k = 0; + while(i < LEFT_SIZE && j < RIGHT_SIZE){ + if(left[i] < right[j]){ + arr[k] = left[i]; + i++; + k++ + }else{ + arr[k] = right[j]; + j++; + k++; + } + } + + while(i < LEFT_SIZE){ + arr[k] = left[i]; + i++; + k++; + } + + while(j < RIGHT_SIZE){ + arr[k] = right[j]; + i++; + k++; + } +} + +//分治法 +void merge_sort(int arr[], int L, int R){ + if(L == R)//如果只有一个元素 + return; + + int M = (L + R) / 2;//为什么要加L,不直接R/2 ? 右边的L是从M+1开始的,并不是0 + merge_sort(arr, L, M);//这个时候M是包含在左边的 + merge_sort(arr, M + 1, R); + merge(arr, L, M, R);//注意中点边界M +} +******************************************************************************** + +//快速排序 + +//选一个基数,分成两个数组 +int partition(int arr[], int left, int right) +{ + int i = left;//定义左右边界 + int j = right; + + int pivot = arr[left];//将左边的选为基数 + + while(i < j){; + while(i < j && arr[i] < pivot){//从左到右的数小于基数 i就向右移 + i++; + } + + while(j > i && arr[j] > pivot){////从右到左的数小于基数 i就向左移 + j--; + } + //不符合条件就交换 + swap(arr[i], arr[j]); + } + //循环完了之后交换基数于i的位置 + swap(arr[i], pivot); + return i;//返回i的下标 +} + +//分治法,递归去分解每一个数组 +void quick_sort(int arr[], int left, int right) +{ + int pivot_pos; + + if(left < right){ + pivot_pos = partition(arr, left, right); + quick_sort(arr, left, pivot_pos); + quick_sort(arr, pivot_pos + 1, right); + } +} + +******************************************************************************** +//堆排序 +//先建立大(小)顶堆,然后将顶元素与尾元素交换,重新构建大(小)顶堆 +void HeapAdjust(int arr[], int start, int end){ + int tmp = arr[start]; + + for(int i = 2 * start + 1; i <= end; i++){ + if(i < end && arr[i] < arr[i + 1]){ + i++; + } + + if(tmp > arr[i]) + { + break; + } + + arr[start] = arr[i]; + start = i; + } + + arr[start] = tmp; +} diff --git "a/\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.md" "b/\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.md" new file mode 100644 index 0000000..928eaa2 --- /dev/null +++ "b/\345\220\210\345\271\266\344\270\244\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.md" @@ -0,0 +1,24 @@ +#### 合并两个有序链表 +递归写法 +```c +public ListNode merge(ListeNode list1, ListNode list2) +{ + if(list1 == null) + return list2; + if(list2 == null) + return list1; + + ListNode listnode = null; + if(list1->val() < list2->val()) + { + listnode = list1; + listnode.next = merge(list1->next,list2); + } + else{ + listnode = list2; + listnode.next = merge(list1, list2->next); + } + + return listnode; +} +``` diff --git "a/\346\234\200\351\225\277\344\270\215\351\207\215\345\244\215\345\255\220\344\270\262.md" "b/\346\234\200\351\225\277\344\270\215\351\207\215\345\244\215\345\255\220\344\270\262.md" new file mode 100644 index 0000000..98d8d95 --- /dev/null +++ "b/\346\234\200\351\225\277\344\270\215\351\207\215\345\244\215\345\255\220\344\270\262.md" @@ -0,0 +1,28 @@ +Given "abcabcbb", the answer is "abc", which the length is 3. +Given "bbbbb", the answer is "b", with the length of 1. +Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. + +滑动窗口是数组/字符串问题中常用的抽象概念。窗口是数组/字符串中通常由开始和结束索引定义的元素范围,即[i,j)(左闭合,右开)。滑动窗口是一个窗口,将其两个边界滑动到某个方向。例如,如果我们通过一个元素将[i,j)向右滑动,则它变为[i + 1,j + 1)(左闭右开)。 + +回到我们的问题。我们使用HashSet将字符存储在当前窗口[i,j)(j = i)。然后我们将索引j向右滑动。如果不在HashSet中,我们会进一步滑动j。这样做直到s[j]已经在HashSet中。在这一点上,我们发现没有重复字符的子字符串的最大大小从索引i开始。重复上面的步骤,我们就能得到我们的答案。 + +```java +public class Solution { + public int lengthOfLongestSubstring(String s) { + int n = s.length(); + Set set = new HashSet<>(); + int ans = 0, i = 0, j = 0; + while (i < n && j < n) { + // try to extend the range [i, j] + if (!set.contains(s.charAt(j))){ + set.add(s.charAt(j++)); + ans = Math.max(ans, j - i); + } + else { + set.remove(s.charAt(i++)); + } + } + return ans; + } +} +```