日常思维练习
来源:互联网 发布:京东抢卷软件 编辑:程序博客网 时间: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
- 日常思维练习
- 日常思维练习(2)
- 日常练习
- 日常练习
- 日常练习
- 日常练习
- 日常练习[perl]
- Java新手日常练习
- 日常练习随笔
- 【JAVA 日常练习】+ IO
- 日常练习(9)
- python之日常练习
- [日常练习]算
- 日常练习代码
- 日常练习代码
- 日常练习代码
- MySQL日常练习;
- 数据结构练习--日常更新
- java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
- oracle执行计划
- 百叶窗特效(用move.js库)
- java热部署filesync
- 24、C#:WinForm和Oracle之在设计表的时候,一定要记录所有的细节
- 日常思维练习
- no input file specified解决道路
- luajit: not enough memory
- ListView的用法
- 机器学习实战 第九章回归树错误
- Android Studio上传代码到GitHub
- 欢迎使用CSDN-markdown编辑器
- 简学Python第二章__巧学数据结构文件操作
- beego ORM配置及使用实例