参考这里。
void mergeSort(int arr[], int tmp[], int start, int end) { // 调用 merge(arr, tmp, 0, len-1);
if(start>=end) return; // 当只有一个元素时,停止递归
int mid=(start+end)/2; // 将区间一分为二
int s1=start, e1=mid;
int s2=mid+1, e2=end;
mergeSort(arr, tmp, s1, e1);
mergeSort(arr, tmp, s2, e2);
int k=start;
while(s1<=e1 && s2<=e2)
tmp[k++]=arr[s1]<=arr[s2]?arr[s1++]:arr[s2++];
while(s1<=e1) // 该组数据有剩余
tmp[k++]=arr[s1++];
while(s2<=e2) // 第二组数据有剩余
tmp[k++]=arr[s2++];
for(k=start; k<=end; ++k)
arr[k]=tmp[k];
}
参考这里。
归并排序(C++递归实现)
// 需要用到额外数组
void merge( int a[], int b[], int n1, int n2, int res[]){
for(int i=0; i
参考这里
int getLargestValue(vector& v, vector& w, int c){
vector > result(v.size(), vector(c+1, 0));
for(int i=1; i<=v.size(); ++i){
for(int j=1; j<=c; ++j){
if(j
bool isDuplication=true;
int getDuplication(int arr[],int n){
if(arr==nullptr || n<=1){
isDuplication=false;
return 0;
}
for(int i=0;i
bool findNumberInMatrix(int arr[], int key, int rows, int cols){
bool find=false;
if(arr!=nullptr && rows>0 && cols>0 ){
int row=0;
int col=cols-1;
while(row=0){
if(keyarr[row][col]){
++row;
}
else{
find=true;
break;
}
}
}
return find;
}
const int g_MaxNumberLength = 10; // 假设数组元素的最大位数为10位
char* g_StrCombine1 = new char[g_MaxNumberLength * 2 + 1]; // 两个数合并后需要的位数
char* g_StrCombine2 = new char[g_MaxNumberLength * 2 + 1];
int compare(const void* strNumber1, const void* strNumber2)
{
// 自定义一个排序规则
// 返回值<0表示strNumber1排在strNumber2的前面,返回值>0表示strNumber1排在strNumber2的后面,=0表示二者相等
strcpy(g_StrCombine1, *(const char**)strNumber1);
strcat(g_StrCombine1, *(const char**)strNumber2);
strcpy(g_StrCombine2, *(const char**)strNumber2);
strcat(g_StrCombine2, *(const char**)strNumber1);
// strcmp(str1,str2):若str1str2,返回正数
return strcmp(g_StrCombine1, g_StrCombine2);
}
void PrintMinNumber(int* numbers, int length)
{
if (numbers == nullptr || length < 0)
return;
char** strNumbers = new char*[length]; // 创建一个二维字符数组,每一行以字符形式存储一个数
for (int i = 0; i < length; ++i) {
strNumbers[i] = new char[g_MaxNumberLength + 1];
sprintf(strNumbers[i], "%d", numbers[i]);
}
// 指针类型在32位编译器下占4个字节,在64位编译器下占8个字节。
//调用库函数来排序
//因为字符串数组里面保存的都是指针
//所以size在传参的时候要传指针的大小
qsort(strNumbers, length, sizeof(char*), compare); // 数组排序函数:qsort(数组首地址,数组元素个数,每个元素大小,比较函数)
for (int i = 0; i < length; ++i)
printf("%s", strNumbers[i]); // 依次输出
printf("\n");
for (int i = 0; i < length; ++i)
delete[] strNumbers[i];
delete[] strNumbers;
}
void permutation(char* str, char* pBegin){
if(str==nullptr || pBegin==nullptr) return;
if(*pBegin=='\0') {
cout << *str << endl;
}
else {
for(char* ch=*pBegin; *ch != '\0' ; ++ch){
char tmp = *pBegin; // 将第一个字符与后面的字符交换
*pBegin = *ch;
*ch = tmp;
permutation(str, pBegin+1);
tmp = *pBegin; // 将前面的交换再换回来,以便继续将第一个字符与其他字符交换
*pBegin = *ch;
*ch = tmp;
}
}
}
// 如何处理非法输入?
// 如何处理正负号
// 如何处理溢出
bool g_isNumber = true;
int strToInt(char* string){
if(string==nullptr){
g_isNumber = false;
return 0;
}
int sign=1;
if(*string=='-'){
sign=-1;
++string;
}
else if(*string=='+'){
sign=1;
++string;
}
int num=0;
while(*string!='\0'){
char c=*string;
if(c>='0' && c<='9'){
num=num*10+(*string)-'0';
++string;
}
else{
g_isNumber=false;
return 0;
}
}
g_isNumber=true;
return num*sign;
}
// length为字符数组的总长度
void replaceBlank(char* string, int length){
if(string==nullptr || length<=0) return;
int originalLength=0;
int numberOfBlank=0;
int i=0;
while(string[i]!='\0'){
++originalLength;
if(string[i]==' ') ++numberOfBlank;
++i;
}
int newLength=originalLength+numberOfBlank*2;
if(newLength>=length)return;
int indexOfOriginal=originalLength;
int indexOfNew=newLength;
while(indexOfOriginal>=0 && indexOfNew>indexOfOriginal){
if(string[indexOfOriginal]==' '){
string[indexOfNew--]='0';
string[indexOfNew--]='2';
string[indexOfNew--]='%';
}
else{
string[indexOfNew--]=string[indexOfOrigin];
}
--indexOfOriginal;
}
}
基本思路:倒数第k个结点到最后一个结点需要走k-1步,第一个结点到最后一个结点需要走n-1步,因此需要从第一个结点走 n − k n-k n−k步才能走到倒数第k个结点。第一阶段,我们可以先让一个指针从第一个结点开始走k-1步,第二阶段,再让另一个指针从第一个结点开始 和 该指针一起走,直到该指针到达最后一个结点,另一个指针指向的结点就是倒数第k个结点,(因为第二阶段走了 n − k n-k n−k步)
// k=0如何处理?
// k>n如何处理?
ListNode* findKthToTail(ListNode* pHead, int k){
if(pHead==nullptr || k<=0) return nullptr;
int length=0;
ListNode* pA=pHead;
ListNode* pB=pHead;
while(pA!=nullptr){ // 计算链表结点总个数
++length;
pA=pA->next;
}
if(k>length) return length;
pA=pHead;
for(int i=0;inext;
}
while(pA->next != nullptr){
pA=pA->next;
pB=pB->next;
}
return pB;
}
BiNode* construct(int* preOrder, int* inOrder, int length){
if(preOrder==nullptr || inOrder==nullptr || length<=0)
return nullptr;
return constructCore(preOrder, preOrder+length-1, inOrder, inOrder+length-1);
}
BiNode* constructCore(int* startPreOrder, int* endPreOrder, int* startInOrder, int* endInOrder){
int rootValue=startPreOrder[0]; // 先序遍历的第一个数为根结点
BiNode* root=new BiNode();
root->value=rootValue;
root->left=root->right=nullptr;
if(startPreOrder==endPreOrder){ // 递归出口:先序遍历集合中只有一个元素
if(startInOrder==endInOrder && *startPreOrder=*startInOrder){
return root;
}
else{
throw std::exception("Invalid Input.");
}
}
int* rootInOrder=startInOrder;
while(rootInOrder<=endInOrder && *rootInOrder!=rootValue){
++rootInOrder; // 在中序遍历中找到根节点
}
if(rootInOrder>endInOrder){
throw std::exception("Invalid Input.");
}
int leftLength=rootInOrder-startInOrder; // 计算左子树结点个数
int* leftPreOrderEnd=startPreOrder+leftLength; // 计算左子树区间
if(leftLength>0){
root->left=constructCore(startPreOrder+1, leftPreOrderEnd, startInOrder, rootInOrder-1); // 重建左子树
}
if(leftLengthright=constructCore(leftPreOrderEnd+1, endPreOrder, rootInOrder+1, endInOrder); // 重建右子树
}
return root;
}
BiNode* getNext(BiNode* pNode){
if(pNode==nullptr) return nullptr;
BiNode* pNext=nullptr;
if(pNode->right!=nullptr){
BiNode* pRight=pNode->right;
while(pRight->left!=nullptr)
pRight=pRight->left;
pNext=pRight;
}
else if(pNode->parent!=nullptr){
BiNode* pCurrent=pNode;
BiNode* pParent=pNode->parent;
while(pParent!=nullptr && pParent->right==pCurrent){
pCurrent=pParent;
pParent=pParent->parent;
}
pNext=pParent;
}
return pNext;
}