日常思维练习

来源:互联网 发布:京东抢卷软件 编辑:程序博客网 时间:2024/05/16 02:04

1.数字在排序数组中出现的次数

使用二分法,可以将时间复杂度变成O(logn)

代码

#include <iostream>using namespace std;int getFirstK(int *arr, int len, int k, int s, int e){    if (arr == NULL || len <= 0 || s > e || s < 0 || e < 0)//参数检验    {        return -1;    }    int start = s;//0    int end = e;//7    int mid = (end - start) / 2 + start;    if (arr[mid] < k)//说明k在后半段    {        s = start + mid + 1;        return getFirstK(arr, len - mid - 1, k, s, e);    }    else if (arr[mid]>k || (arr[mid] == k && arr[mid - 1] == k))    {//说明k在前半段        e = len - mid - 2;        return getFirstK(arr, len - mid - 1, k, s, e);    }    else    {        return mid;    }}int getLastK(int *arr, int len, int k, int s, int e){    if (arr == NULL || len <= 0 || s > e || s < 0 || e < 0)    {        return -1;    }    int start = s;//0    int end = e;//7    int mid = (end - start) / 2 + start;    if (arr[mid] < k || (arr[mid] == k && arr[mid + 1] == k))//说明k在后半段    {        s = start + mid + 1;        return getLastK(arr, len - mid - 1, k, s, e);    }    else if (arr[mid]>k )    {//说明k在前半段        e = len - mid - 2;        return getLastK(arr, len - mid - 1, k, s, e);    }    else    {        return mid;    }}int getNumTime(int *a, int len,int k){    int start = getFirstK(a, len, k, 0, len - 1);    int end = getLastK(a, len, k, 0, len - 1);    if (start < 0 || end < 0)//表示没有这样的数字    {        return -1;    }    return end - start + 1;//坐标计算应当加一个1}int main(){    //int a[8] = { 1,2,3,3,3,3,4,5 };    //int a[8] = { 1,2,3,4,5 };    int a[8] = { 1,2,4,4,5 };    cout << getFirstK(a, 5, 3, 0, 4) << endl;    cout << getLastK(a, 5, 3, 0, 4) << endl;    cout << getNumTime(a, 5, 3) << endl;    return 0;}

2.二叉树深度和拓展
二叉树深度:

int getDepth(treeNode* s){    if (s == NULL)    {        return 0;    }    else    {        int tmp1 = getDepth(s->left);        int tmp2 = getDepth(s->right);        return (tmp1> tmp2 ? tmp1 : tmp2) + 1;    }}判断是否是平衡二叉树:bool isBalance(treeNode* s){    if (s == NULL)    {        return true;    }    int left = getDepth(s->left);    int right = getDepth(s->right);    if (abs(left - right) > 1)    {        return false;    }    return isBalance(s->left) && isBalance(s->right);}优化判断:bool isBetterBalance(treeNode* pRoot,int* pDepth)//减少了重复对结点访问的操作{    if (pRoot == NULL)    {        *pDepth = 0;        return true;    }    int left, right;    if (isBetterBalance(pRoot->left, &left) &&        isBetterBalance(pRoot->right, &right))    {        int diff = left - right;        if (diff <= 1 && diff >= -1)        {            *pDepth = 1+(left > right ? left : right);            return true;        }    }    return false;}bool isBetterBalanced(treeNode* pRoot){    int depth = 0;    return isBetterBalance(pRoot, &depth);}

3.数组中只出现一次的数字
一个整形数组里除了两个数字之外其他数字都出现了两次

unsigned int FindFirstBitIs1(int num){    int indexBit = 0;    while ((num & 1) == 0 && (indexBit < 8 * sizeof(int)))    {        num = num >> 1;        ++indexBit;    }    return indexBit;}bool IsBit1(int num, unsigned int indexBit){    num = num >> indexBit;    return (num & 1);}void FindNumsAppearOnce(int data[], int length, int* num1, int* num2){    if (data == NULL || length < 2)        return;    int resultExclusiveOR = 0;    for (int i = 0; i < length; ++i)    {        resultExclusiveOR ^= data[i];    }    unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);    *num1 = *num2 = 0;    for (int j = 0; j < length; ++j)    {        if (IsBit1(data[j], indexOf1))//为1的在一起相抑或        {            *num1 ^= data[j];        }        else        {            *num2 ^= data[j];        }    }}int main(){    int arr[8] = { 2,4,3,6,3,2,5,5 };    int tmp1;    int tmp2;    FindNumsAppearOnce(arr, 8, &tmp1, &tmp2);    cout << tmp1<<endl;    cout << tmp2<<endl;    return 0;}

4.和为k的两个数字
数组是有序递增数组

bool findCoupleSumk(int* a, int len, int* tmp1, int* tmp2, int k){    if (a == NULL || len <= 1)    {        return false;    }    int *p1 = &a[0];    int *p2 = &a[len - 1];    while (*p1 + *p2 != k&&p1 != p2)    {        if (*p1 + *p2 < k)        {            p1++;        }        else        {            p2--;        }    }    if (p1 == p2)    {        return false;    }    *tmp1 = *p1;    *tmp2 = *p2;    return true;}拓展:连续数组void findSum(int *arr, int len, int k){    if (arr == NULL || len <= 0 || k < 3)//要考虑参数k有无可能输入错误    {        cout << "无" << endl;        return;    }    if (len == 1 && arr[0] == k)    {        cout << arr[0] << endl;        return;    }    else if (len == 1 && arr[0] != k)    {        cout << "无" << endl;        return;    }    int first = 0;    int second = 1;    int sum = 0;    int flag = false;    while (second <= len - 1 && first <= second)    {        for (int i = first; i <= second; ++i)        {            sum += arr[i];        }        if (sum < k)        {            second++;            sum = 0;        }        else if (sum>k)        {            first++;            sum = 0;        }        else        {            flag = true;            for (int i = first; i <= second; ++i)            {                cout << arr[i] << " ";            }            cout << endl;            sum = 0;            second++;        }    }    if (flag == false)    {        cout << "没有连续数的和是" << k << "的值\n";    }}int main(){    int arr[8] = { 1,2,3,4,5,6,7,8 };    int* brr = NULL;    findSum(arr, 8, 15);    findSum(arr, 8, 1001);    findSum(brr, 0, 15);    return 0;}

5.
反转单词顺序以及左旋转字符串

void reserve(char* p1,char* p2,int len){    if (p1 == p2)    {        return;    }    char tmp;    int time = 0;    while (p1 != p2&&time<len/2)    {        tmp = *p1;        *p1 = *p2;        *p2 = tmp;        p1++;        p2--;        time++;    }}void reserveWord(char* arr,int len){    if (arr == NULL||len<=1)    {        return;    }    reserve(&arr[0], &arr[len - 1], len);    cout << arr << endl;    char* p1 = &arr[0];    char* p2 = &arr[0];    int tmp = 0;    while (*p2 != '\0')    {        if (*p2 == ' ')        {            reserve(p1, p2-1, tmp);            p1 += tmp+1;            p2 = p1;            tmp = 0;        }        p2++;        tmp++;    }}//拓展:英文左旋转char *LeftRotateString(char* pStr, int n){    if (pStr != NULL)    {        int nlength = static_cast<int>(strlen(pStr));        if (nlength > 0 && n > 0 && n < nlength)        {            char* pFirstStart = pStr;            char* pFirstEnd = pStr + n - 1;            char* pSecondStart = pStr + n;            char *pSecondEnd = pStr + nlength - 1;            reserve(pFirstStart, pFirstEnd, n );            reserve(pSecondStart, pSecondEnd, nlength - n);//7 2            reserve(pFirstStart, pSecondEnd, nlength - 1);        }    }    return pStr;}int main(){//  char a[] = "I am a student.";//  reserveWord(a, strlen(a));//  cout << a << endl;    char arr[] = "abcdefg";    char* p = LeftRotateString(arr, 2);    cout << p << endl;    return 0;}
0 0