Cranking the Coding Interview: Sorting and Searching
2017-03-27 09:34
417 查看
No buffer interchange
Group angrams
Sparse Search
Search in Rotated Array
word frequency
no if max implementation
chess board
guess score
给定一个int数组AB,其第零个元素和第一个元素为待交换的值,请返回交换后的数组。
给定一个string的数组str和数组大小int n,请返回排序合并后的数组。保证字符串串长小于等于20,数组大小小于等于300。
在这道题目中有两个需求,一个是去重保留顺序更前面的字符串,第二个是对不重复的字符串进行排序。
代码实现:
有一个排过序的字符串数组,但是其中有插入了一些空字符串,请设计一个算法,找出给定字符串的位置。算法的查找部分的复杂度应该为log级别。
给定一个string数组str,同时给定数组大小n和需要查找的string x,请返回该串的位置(位置从零开始)。
代码实现:
给定一个int数组A,为移位后的数组,同时给定数组大小n和需要查找的元素的值x,请返回x的位置(位置从零开始)。保证数组中元素互异。
就是将一个数组进行旋转,然后找到需要找到的数字的索引,然后返回。
这里需要注意的就是索引的使用会有些复杂。
这里我实现的思路是先找到最小元素的索引,在这个基础上,在进行二分查找。
代码实现:
给定一个string数组article和数组大小n及一个待统计单词word.
代码实现:
给定两个int a和b,请返回较大的一个数。若两数相同则返回任意一个。
这道题目里,不能使用if else这样的结构,那么就需要进行一些逻辑判断,使用逻辑运算来代替if else的结构。
代码实现:
给定一个二维数组board,代表当前棋盘,其中元素为1的代表是当前玩家的棋子,为0表示没有棋子,为-1代表是对方玩家的棋子。
判断一个棋盘中当前玩家是否赢了。
既然这道题目的棋盘大小是固定的,那么就可以直接判断。
代码实现:
给定两个string A和guess。分别表示颜色组合,和一个猜测。请返回一个int数组,第一个元素为猜中的次数,第二个元素为伪猜中的次数。
这道题目比较简单,其实只需要把字符创中相等的部分进行计算得到第一个返回的数据。然后第二个返回的数据就排除第一次比较相等的数据,然后使用一个哈希表记录即可得到正确的结果。
Group angrams
Sparse Search
Search in Rotated Array
word frequency
no if max implementation
chess board
guess score
No buffer interchange
函数内不使用任何临时变量,直接交换两个数的值。给定一个int数组AB,其第零个元素和第一个元素为待交换的值,请返回交换后的数组。
class Exchange { public: vector<int> exchangeAB(vector<int> AB) { AB[0] = AB[1] - AB[0]; AB[1] = AB[1] - AB[0]; AB[0] = AB[0] + AB[1]; return AB; } };
Group angrams
对一个字符串数组进行排序,将所有变位词合并,保留其字典序最小的一个串。这里的变位词指变换其字母顺序所构成的新的词或短语。例如”triangle”和”integral”就是变位词。给定一个string的数组str和数组大小int n,请返回排序合并后的数组。保证字符串串长小于等于20,数组大小小于等于300。
在这道题目中有两个需求,一个是去重保留顺序更前面的字符串,第二个是对不重复的字符串进行排序。
代码实现:
class SortString { public: __inline void calculateHash(vector<int>& hash, string str) { for(int i = 0, sz = str.length(); i < sz; i++) hash[str[i]-'a']++; } __inline void mergeSort(vector<string>& res, vector<string>& helper, int low, int high) { if(low < high) { int mid = (low + high) >> 1; mergeSort(res, helper, low, mid); mergeSort(res, helper, mid+1, high); mergeArray(res, helper, low, mid, high); } } void mergeArray(vector<string>& arr1, vector<string>& arr2, int low, int mid, int high) { for(int i = low; i <= high; i++) arr2[i] = arr1[i]; int helperLeft = low, helperRight = mid+1, cur = low; while(helperLeft <= mid && helperRight <= high) { if(arr2[helperLeft] <= arr2[helperRight]) { arr1[cur] = arr2[helperLeft]; helperLeft++; } else { arr1[cur] = arr2[helperRight]; helperRight++; } cur++; } int rem = mid - helperLeft; for(int i = 0; i <= rem; i++) arr1[cur+i] = arr2[helperLeft + i]; } vector<string> sortStrings(vector<string> str, int n) { vector<string> res; vector<vector<int>> hash_table(300, vector<int>(26, 0)); if(!n) return res; res.push_back(str[0]); calculateHash(hash_table[0], str[0]); for(int i = 1; i < n; i++) { vector<int> hash_cur(26, 0); calculateHash(hash_cur, str[i]); for(int j = 0, cur_size = res.size(); j < cur_size; j++) { if(hash_cur == hash_table[j]) { if(str[i] < res[j]) res[j] = str[i]; } else if(j == cur_size - 1){ res.push_back(str[i]); hash_table[cur_size] = hash_cur; } } } vector<string> helper(res.size(), ""); mergeSort(res, helper, 0, res.size() - 1); return res; } };
Sparse Search
一个稀疏矩阵需要进行二分查找,需要注意字符串为空的情况。有一个排过序的字符串数组,但是其中有插入了一些空字符串,请设计一个算法,找出给定字符串的位置。算法的查找部分的复杂度应该为log级别。
给定一个string数组str,同时给定数组大小n和需要查找的string x,请返回该串的位置(位置从零开始)。
代码实现:
class Finder { public: int findString(vector<string> str, int n, string x) { int low = 0, high = n - 1; while(low <= high) { while(str[low].empty()) low++; while(str[high].empty()) high--; int mid = (low + high) >> 1; int leftBnd = mid, rightBnd = mid; while(leftBnd >= low && str[leftBnd].empty()) leftBnd--; while(rightBnd <= high && str[rightBnd].empty()) rightBnd++; if(str[leftBnd] == x || str[rightBnd] == x) return leftBnd; else if(str[rightBnd] < x) low = rightBnd + 1; else if(str[leftBnd] > x) high = leftBnd - 1; } return -1; } };
Search in Rotated Array
有一个排过序的数组,包含n个整数,但是这个数组向左进行了一定长度的移位,例如,原数组为[1,2,3,4,5,6],向左移位5个位置即变成了[6,1,2,3,4,5],现在对于移位后的数组,需要查找某个元素的位置。请设计一个复杂度为log级别的算法完成这个任务。给定一个int数组A,为移位后的数组,同时给定数组大小n和需要查找的元素的值x,请返回x的位置(位置从零开始)。保证数组中元素互异。
就是将一个数组进行旋转,然后找到需要找到的数字的索引,然后返回。
这里需要注意的就是索引的使用会有些复杂。
这里我实现的思路是先找到最小元素的索引,在这个基础上,在进行二分查找。
代码实现:
class Finder { public: int findElement(vector<int> A, int n, int x) { int low = 0, high = n - 1, mid = 0; while (low <= high) { mid = (low + high) >> 1; if (A[mid] > A[low]) low = mid; else if (A[mid] < A[high]) high = mid; else { if (A[high] < A[low]) { mid = high; break; } else { mid = low; break; } } } low = mid, high = mid ? mid - 1 : n - 1; int abt_low = 0, abt_high = n - 1; while (abt_low <= abt_high) { int abt_mid = (abt_low + abt_high) >> 1; mid = (abt_mid + low) % n; if (A[mid] > x) abt_high = abt_mid - 1; else if (A[mid] < x) abt_low = abt_mid + 1; else return mid; if (A[(abt_low + low) % n] == x) return (abt_low + low) % n; if (A[(abt_high + low) % n] == x) return (abt_high + low) % n; } return -1; } };
word frequency
请设计一个高效的方法,找出任意指定单词在一篇文章中的出现频数。给定一个string数组article和数组大小n及一个待统计单词word.
代码实现:
class Frequency { public: __inline bool isEqual(string a, string b) { int lena = a.size(), lenb = b.size(); if(lena != lenb) return false; for(int i = 0; i < lena; i++) if(a[i] ^ b[i]) return false; return true; } int getFrequency(vector<string> article, int n, string word) { int res = 0; for(int i = 0; i < n; i++) { res += isEqual(word, article[i]); } return res; } };
no if max implementation
请编写一个方法,找出两个数字中最大的那个。条件是不得使用if-else等比较和判断运算符。给定两个int a和b,请返回较大的一个数。若两数相同则返回任意一个。
这道题目里,不能使用if else这样的结构,那么就需要进行一些逻辑判断,使用逻辑运算来代替if else的结构。
代码实现:
class Max { public: int getMax(int a, int b) { int bs = ((a - b) >> 31) & 1; int as = 1 - bs; for(int i = 1; i < 32; i++) { bs = bs | (bs << i); as = as | (as << i); } return (bs & b) | (as & a); } };
chess board
对于一个给定的井字棋棋盘,请设计一个高效算法判断当前玩家是否获胜。给定一个二维数组board,代表当前棋盘,其中元素为1的代表是当前玩家的棋子,为0表示没有棋子,为-1代表是对方玩家的棋子。
判断一个棋盘中当前玩家是否赢了。
既然这道题目的棋盘大小是固定的,那么就可以直接判断。
代码实现:
class Board { public: bool checkWon(vector<vector<int> > board) { for(int row = 0; row < 3; row++) { for(int col = 0; col < 3; col++) { if(board[row][col] == 1) { if(col == 0) { // 1 if(board[row][1] == 1 && board[row][2] == 1) return true; // 2 if(row == 0) { if(board[1][1] == 1 && board[2][2] == 1) return true; } } // 3 if(row == 0) { if(board[1][col] == 1 && board[2][col] == 1) return true; // 4 if(col == 2) { if(board[1][1] == 1 && board[2][0] == 1) return true; } } } } } return false; } };
guess score
我们现在有四个槽,每个槽放一个球,颜色可能是红色(R)、黄色(Y)、绿色(G)或蓝色(B)。例如,可能的情况为RGGB(槽1为红色,槽2、3为绿色,槽4为蓝色),作为玩家,你需要试图猜出颜色的组合。比如,你可能猜YRGB。要是你猜对了某个槽的颜色,则算一次“猜中”。要是只是猜对了颜色但槽位猜错了,则算一次“伪猜中”。注意,“猜中”不能算入“伪猜中”。给定两个string A和guess。分别表示颜色组合,和一个猜测。请返回一个int数组,第一个元素为猜中的次数,第二个元素为伪猜中的次数。
这道题目比较简单,其实只需要把字符创中相等的部分进行计算得到第一个返回的数据。然后第二个返回的数据就排除第一次比较相等的数据,然后使用一个哈希表记录即可得到正确的结果。
class Result { public: vector<int> calcResult(string A, string B) { int hash[4] = {0}; // 1, 2, 3, 4 int rgb[4] = {0}; vector<int> res(2, 0); for(int i = 0; i < 4; i++) { if(A[i] ^ B[i]) hash[i] = INT_MAX; else res[0]++; } for(int i = 0; i < 4; i++) { if(hash[i] == INT_MAX) { switch(A[i]) { case 'R': { if(rgb[0] < 0) res[1]++; rgb[0]++; break; } case 'G': { if(rgb[1] < 0) res[1]++; rgb[1]++; break; } case 'Y': { if(rgb[2] < 0) res[1]++; rgb[2]++; break; } default: { if(rgb[3] < 0) res[1]++; rgb[3]++; } } switch(B[i]) { case 'R': { if(rgb[0] > 0) res[1]++; rgb[0]--; break; } case 'G': { if(rgb[1] > 0) res[1]++; rgb[1]--; break; } case 'Y': { if(rgb[2] > 0) res[1]++; rgb[2]--; break; } default: { if(rgb[3] > 0) res[1]++; rgb[3]--; } } } } return res; } };
相关文章推荐
- Cranking the Coding Interview: Recursion and Dynamic Programming
- Cranking the Coding Interview: C1 Array and String
- Cranking the Coding Interview: Stacks and Queues
- Cracking the Coding Interview-ch11 | System Design and Memory Limits
- Cracking the Coding Interview 题目分析笔记—— Array and String
- Cracking the Coding Interview(Stacks and Queues)
- Cracking the Coding Interview: Trees and Graphs
- Cranking the Coding Interview: Bit Manipulation
- Cracking the Coding Interview(Stacks and Queues)
- [Cracking the Coding Interview] Chapter 1 - Arrays and Strings
- Cracking the Coding Interview(String and array)
- Cracking the coding interview 150 要点记录(一)--Array and List
- Cracking the Coding Interview(Trees and Graphs)
- [Cracking the Coding Interview] Chapter 3 - Stacks and Queues
- Cracking the Coding Interview(Trees and Graphs)
- C1-Arrays and String【Cracking the Coding Interview 习题解答】
- { Cracking The Coding Interview: 150 programming Q&A } --- Arrays and Strings
- Cranking The Coding Interview: 12
- Cracking the Coding Interview: Math and Logic Puzzles
- Cracking The Coding Interview 9.0