日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【剑指Offer】俯视50题之31 - 40题

發布時間:2025/4/16 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【剑指Offer】俯视50题之31 - 40题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【劍指Offer】俯視50題之31 - 40題

面試題31連續子數組的最大和?

面試題32從1到n整數中1出現的次數?

面試題33把數組排成最小的數?

面試題34丑數?

面試題35第一個僅僅出現一次的字符?

面試題36數組中的逆序對

面試題37兩個鏈表的第一個公共結點?

面試題38數字在排序數組中出現的次數?

面試題39二叉樹的深度?

面試題40數組中僅僅出現一次的數字?

/*******************************************************/

面試題31連續子數組的最大和?,輸入一個數組。數組里面有正數,也有負數。

求連續數的最大值

實現例如以下:

int MaxSum(int num[], int length) {int CurrentSum = 0;int iResult = 0x80000000;if (num == NULL || length < 0){return 0;/* invalid */}for (int i = 0; i < length; i++){if (CurrentSum <= 0){CurrentSum = num[i];}else{CurrentSum += num[i];}if (CurrentSum > iResult)iResult = CurrentSum;}return iResult; }

面試題32從1到n整數中1出現的次數?,輸入一個N,求1到N全部的整數中1出現的次數

實現例如以下:

#include <iostream>int CountNum(int n) {int iCurrentNum = 0;/* 當前位的數 */int iNTemp = n;int iResult = 0;int iBase = 1; /* 個位 */int iRemain = 0;if (n <= 0){return 0;}while (iNTemp > 0){iCurrentNum = iNTemp % 10;iNTemp = iNTemp/10;if (iCurrentNum > 1){iResult+= (iNTemp + 1)*iBase;}else if (iCurrentNum == 1){iResult+= (iNTemp)*iBase + iRemain + 1;}else if (iCurrentNum == 0){iResult+= (iNTemp)*iBase;}iRemain += iCurrentNum*iBase; /* 先計算剩余數大小*/iBase = iBase*10; /**然后計算下次base位*/ }return iResult; }int main() {printf("%d\n",CountNum(11)); }

面試題33把數組排成最小的數?

實現例如以下:

#include <iostream> #define MAX_NUM_LENGTH 10int compare(const void *str1, const void *str2) {char str1Temp[MAX_NUM_LENGTH*2 +1];char str2Temp[MAX_NUM_LENGTH*2 +1];strcpy(str1Temp, (const char*)str1);strcat(str1Temp, (const char*)str2);strcpy(str2Temp, (const char*)str2);strcat(str2Temp, (const char*)str1);return strcmp(str1Temp,str2Temp);} void GetMinNum(int num[], int length) {char **numStr = (char **)malloc(length + 1);for (int i = 0; i < length; i++){numStr[i] = (char *)malloc(MAX_NUM_LENGTH +1);sprintf(numStr[i],"%d",num[i]);}qsort(numStr,length,sizeof(char *),compare);for (int i = 0; i < length; i++){printf("%s",numStr[i]);}/* 釋放內存 */for (int i = 0; i < length; i++){free(numStr[i]);}free(numStr);}int main() {int num[] = {1,234,341};GetMinNum(num, 3); }

面試題34丑數?

實現例如以下:

#include <iostream> #define MAX_NUM_LENGTH 10int min(int a, int b, int c) {int min = (a>b)?b:a;min = (min > c)?

c:min; return min; } /* 僅僅能被2、3、5整除的 */ int GetUglyNum(int n) { /* 創建一個n個元素的數組 */ int UglyNum[n]; int p2 = 0; int p3 = 0; int p5 = 0; int NextIndex = 1; UglyNum[0] = 1; while(NextIndex < n) { UglyNum[NextIndex] = min(UglyNum[p2]*2, UglyNum[p3]*3 ,UglyNum[p5]*5); while(UglyNum[p2]*2 <= UglyNum[NextIndex]) { p2++; } while(UglyNum[p3]*3 <= UglyNum[NextIndex]) { p3++; } while(UglyNum[p5]*5 <= UglyNum[NextIndex]) { p5++; } NextIndex++; } return UglyNum[NextIndex - 1]; } int main() { printf("%d\n",GetUglyNum(3)); }



面試題35第一個僅僅出現一次的字符?

實現例如以下:

#include <iostream> #define VOS_OK 0 #define VOS_ERR 1/* 僅僅能被2、3、5整除的 */ int GetFirstChar(char *str, char *result) {unsigned int hashNum[256] = {0};char *p;if (str == NULL){return VOS_ERR;}p = str;while(*p != '\0'){hashNum[*p]++;p++;}p = str;while(*p!= '\0'){if (hashNum[*p] == 1){*result = *p;return VOS_OK;}p++;}return VOS_ERR;}int main() {char iChar;if (VOS_OK == GetFirstChar("aabcddb", &iChar)){printf("%c\n",iChar);}else{printf("Error!"); } }

面試題36數組中的逆序對

實現例如以下:

/* 求數組中的逆序對 */ #include <iostream> #define VOS_OK 0 #define VOS_ERR 1 int Merge(int *numA, int begin,int mid, int end) {int startA = begin;int startB = mid + 1;int *numB = (int *)malloc(sizeof(int)*(end + 1));int currentIndex = 0;long long result = 0;if (numA == NULL || begin > mid || mid > end)/* 其余異常函數調用處保證 */{return 0;}while (startA <=mid && startB <= end){if (numA[startA] <= numA[startB]){numB[currentIndex] = numA[startA++];}else{numB[currentIndex] = numA[startB++];/* 前面的大于后面的,則前數組之后的元素也大于該元素 */result += mid - startA + 1;}currentIndex++;}while (startA <= mid){numB[currentIndex++] = numA[startA++];}while (startB <= end){numB[currentIndex++] = numA[startB++];}for (int i = begin; i <= end; i++){numA[i] = numB[i];}free(numB);return result;}int MergeSort(int *num, int start, int end) {int result = 0;int mid;if (num == NULL || start >= end) /* 注意start == end 的時候*/{return 0; }mid = (start + end)>>1;result = MergeSort(num, start, mid) + MergeSort(num, mid +1, end);result += Merge(num,start,mid,end);return result;}int main() {int num[]={2,1,3,5,6};printf("%d\n",MergeSort(num, 0, 4)); }

面試題37兩個鏈表的第一個公共結點?

實現例如以下:

? 1)暴力法

? ? ? ? ?每次遍歷鏈表A,然后將鏈表A中當前結點在鏈表B中查找。假設找到則停止查找,返回。

? 2)空間換取時間

? ? ? ?將兩個鏈表都入棧,然后從最后一個結點開始比較。直到不相等為止。
? 3)同一時候向后查找

?? 先遍歷鏈表A得長度lengthA。再遍歷鏈表B得長度lengthB

?? 假如A比B長n。則A先走n步,假如B比A長n,則B先走n步。

?? 然后同一時候向后走,直到第一個相等的結點


面試題38數字在排序數組中出現的次數?

有兩種思路:利用二分查找法,找到該數中間出現的位置,然后分別向前后遍歷同樣數,可得到該數出現的次數

? ? ?利用二分查找法,找打該數最左邊及最右邊出現的位置。然后就能夠求得該數出現的次數

左右查詢實現例如以下:

#include <iostream> int MaxSum(int num[], int length, int value) {int iResult = 0;int i = 0;int j = length - 1;int mid;int k;while(i <= j ){mid = (i + j)>>1;if (num[mid] > value){j= mid - 1;}else if (num[mid] < value){i = mid + 1;}else{/* 向左查詢*/k = mid-1;while (k >= i &&(num[k] == value)){k--;iResult++;}/* 向右查詢*/k = mid+1;while (k <= j &&(num[k] == value)){ k++;iResult++;}printf("================");return iResult + 1;}}return iResult; }int main() {int num[]={2,2,2,2,5,5,6,6};printf("%d\n",MaxSum(num, 8, 2) );getchar(); }
第二種實現方法:

#include <iostream> int GetFirstK(int num[], int length, int value) {int mid;int i = 0;int j = length - 1;if (num == NULL){return 0;}while (i <= j){mid = (i + j)>>1;if (num[mid] > value){j = mid - 1;}else if (num[mid] < value){i = mid + 1;}else{if (mid -1 >= 0 && (num[mid - 1] == value)){j = mid - 1;}else{return mid;}}}return 0; }int GetLastK(int num[], int length, int value) {int mid;int i = 0;int j = length - 1;if (num == NULL){return 0;}while (i <= j){mid = (i + j)>>1;if (num[mid] > value){j = mid - 1;}else if (num[mid] < value){i = mid + 1;}else{if (mid + 1 <= j && (num[mid + 1] == value)){i = mid + 1;}else{return mid;}}}return 0; }int main() {int num[]={2,2,2,2,5,5,6,6};printf("%d\n",GetLastK(num, 8, 2) - GetFirstK(num, 8, 2) + 1);getchar(); }

面試題39二叉樹的深度?

實現例如以下:

int DepthTree(BinaryNode *root) {int leftDepth = 0;int rightDepth = 0;if (root == NULL){return 0;}leftDepth = DepthTree(root->lchild);rightDepth = DepthTree(root->rchild);retrun (leftDepth > rightDepth)? (leftDepth + 1):(rightDepth + 1); }
擴展題目:推斷一個樹是否是平衡二叉樹

實現例如以下:

bool IsBlanceTree(BinaryNode *root, int *depth) {int leftDepth = 0;int rightDepth = 0;int diff;if (root == NULL){return true;}leftDepth = DepthTree(root->lchild);rightDepth = DepthTree(root->rchild);if (IsBlanceTree(root->lchild, &leftDepth)&&IsBlanceTree(root->rchild, &rightDepth)){diff = leftDepth - rightDepth;if (diff < 1 && diff > -1){*depth = (leftDepth > rightDepth)? (leftDepth + 1):(rightDepth + 1);return true;}}retrun false; }

面試題40數組中僅僅出現一次的數字?:給一個數組,數組中有兩個數僅僅出現一次。其余數出現兩次,求這兩個數

思路:將數組分成兩組,分別異或去重。怎樣分組呢?分組依據異或之后。最后一位二進制值為1的位分組。對數組一進行異或最后得一個數。對數組二異或。最后得還有一個數。

則最后得到的兩個數是所求的數。

實現例如以下:

int FindFirstBitIsOne(int resultOR) {for (int i = 0; i < 32; i++){if (resultOR & (1 << i)){return i;}}return 0;}int IsBitOne(int data, int indexOfOne) {return data & (1<<indexOfOne);} void FindNumsAppearOnce(int data[],int length,int *num1,int num2) {if (data == NULL || length < 2){return;}int resultOR = 0;for (int i = 0; i < length; i++){resultOR ^=data[i];}int indexOfOne = FindFirstBitIsOne(resultOR);for (int j = 0; j < length; j++){if (IsBitOne(data[j], indexOfOne)){*num1 ^=data[j];}else{*num2^=data[j];}}}




posted on 2017-05-24 10:29 mthoutai 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/mthoutai/p/6897666.html

總結

以上是生活随笔為你收集整理的【剑指Offer】俯视50题之31 - 40题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。