Solutions to Chapter 1 | Arrays and Strings
来源:互联网 发布:淘宝开店收入 编辑:程序博客网 时间:2024/04/28 14:32
1.1
Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?
译文:
实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).不能使用额外的数据结构。 (即只使用基本的数据结构)
解答
面试的时候遇到这种题,第一反应就是要去除模糊性,可以通过提问的方式:
1 请问,构成字符串的字符集多大?ASCII还是只有字母和数字组成?
我们假设是ASCII码,那么ASCII码除去128 - 255 扩展的特殊字符,我们假设只有0-127
第一种方法:标记数组法
第二种方法:位操作
int val = str.at(i);int index = val/32;//数组下标int offset = val%32//相应位
整体代码如下:vs 2008 已测试通过
#include <iostream>#include <string>using namespace std;bool boolArrays(string str,bool *a){int len = str.length();for (int i = 0; i < len; i++){int val = str.at(i);if (a[val]){return false;}else{a[val] = true;}}return true;}bool bitOperation(string str,int* a)//int 为32位 128个 128/32 = 4{int len = str.length();for (int i = 0; i < len; i++){int val = str.at(i);int index = val/32;int offset = val%32;int j = 1<<(32 - offset); //关键是这里 别糊涂 我看见有的人的文章这里不对if (a[index]&j){return false;}else{a[index] |= (j);}}return true;}int main(){bool a[128];int b[4];string str = "";memset(a,0,sizeof(a));memset(b,0,sizeof(b)); while(cin>>str){if (boolArrays(str,a)){cout<<"boolArrays true"<<endl;}else{cout<<"boolArrays false"<<endl;}memset(a,0,sizeof(a));if (bitOperation(str,b)){cout<<"bitOperation true"<<endl;}else{cout<<"bitOperation false"<<endl;}memset(b,0,sizeof(b));}return 0;}
1.2
Write code to reverse a C-Style String. (C-String means that “abcd” is represented as five characters, including the null character.)
译文:
写代码翻转一个C风格的字符串。(C风格的意思是"abcd"需要用5个字符来表示,包含末尾的 结束字符)
解答
这道题如果就是要考察你有没有注意到C风格字符串最后的那个结束符,那我觉得还是像书 上写的那样,在代码中有所体现。代码如下:
#include <iostream>using namespace std;void Reverse(char *a){char c;for (int i = 0,j = strlen(a) - 1; i < j; i++,j-- ){c = a[i];a[i] = a[j];a[j] = c;}}int main(){char str[] = "123456789";Reverse(str);cout<<str<<endl;return 0;}
1.3
Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two additional variables are fine. An extra copy of the array is not.
FOLLOW UPWrite the test cases for this method.
译文:
设计算法并写出代码移除字符串中重复的字符,不能使用额外的缓存空间。注意: 可以使用额外的一个或两个变量,但不允许额外再开一个数组拷贝。
进一步地,
为你的程序写测试用例。
解答
First, ask yourself, what does the interviewer mean by an additional buffer? Can we use an additional array of constant size?
Algorithm—No (Large) Additional Memory:
1. For each character, check if it is a duplicate of already found characters.
2. Skip duplicate characters and update the non duplicate characters.
Time complexity is O(N2).
首先,自己默默问一下自己,面试官口中所谓的额外的缓存空间是什么?可以使用具有固定大小的数组吗?
下面是一个不使用额外内存(几个变量而已)版本的算法:
1 对每一个字符,检查是否与前面字符重复
2 跳过(覆盖)重复的字符并且更新不重复的字符
算法复杂度是O(n)
#include <iostream>#include <cstring>using namespace std;void removeDuplicate(char* s){if (s == NULL){return ;}if (strlen(s) < 2){return ;}int tail = 1; //跟踪不重复的元素,也可以理解为当前不重复字符的个数,这样方便覆盖,不用挪动元素int len = strlen(s);for (int i = 1; i < len; ++i) //直接从第二个字符开始检查{int j;for (j = 0;j < tail; ++j){if (s[j] == s[i]){break;}}if ( j == tail) //j等于tail 说明没有被break,当前检测字符与之前的字符没有重复{s[tail] = s[i];++tail;}}s[tail] = '\0';return ;}int main(){ char s[] = "ababababa"; cout<<s<<endl;removeDuplicate(s); cout<<s<<endl;return 0;}
1. String does not contain any duplicates, e.g.: abcd
2. String contains all duplicates, e.g.: aaaa
3. Null string
4. String with all continuous duplicates, e.g.: aaabbb
5. String with non-contiguous duplicate, e.g.: abababa
测试用例:
- 不包含重复字符的字符串,比如:abcd
- 字符串全是重复字符,比如:aaaa
- 空字符串
- 重复字符连续出现,比如:aaabbb
- 重复字符不连续出现,比如:abababa
void removeDuplicate1(char* s){if(s == NULL) return;int len = strlen(s);if(len < 2) return;bool boolArray[128];memset(boolArray,0,sizeof(boolArray));int tail = 0;for (int i = 0; i < len; i++){int val = s[i];if (!boolArray[val]){boolArray[val] = true;s[tail] = s[i];++tail;}}s[tail] = '\0';return;}int main(){char str[] = "abcdeffdsfagdfbfdew";cout<<str<<endl;removeDuplicate1(str);cout<<str<<endl;return 0;}
1.4
Write a method to decide if two strings are anagrams or not.
译文:
写一个函数判断两个字符串是否由相同的字符构成(回文)。
解答
有两种方法解决这个问题:
O(nlogn)的解法
先分别对两个字符串进行排序,排序后的字符串若相等,则是回文,否则不是
bool isAnagram1(string s1, string s2){if(s1 == "" || s2 == "") return false;if(s1.length() != s2.length()) return false;sort(&s1[0], &s1[0]+s1.length());sort(&s2[0], &s2[0]+s2.length());if(s1 == s2) return true;else return false;}
O(n)的解法
检查两个字符串中的每一个字符是否有相同的出现次数,一个++,一个--。若是回文,则最终抵消,否则不是
bool anagrams(string &s1,string &s2){if (s1 == ""||s2 == "") return false;if (s1.length() != s2.length()){return false;}int ascii[128];memset(ascii,0,sizeof(ascii));int len = s1.length(); int val1 = 0,val2 = 0,i;for ( i = 0; i < len; i++){val1 = s1.at(i);val2 = s2.at(i);++ascii[val1];--ascii[val2];}for (i = 0; i < 128; i++){if (ascii[i] != 0){return false;}}return true;}
1.5
Write a method to replace all spaces in a string with ‘%20’.
译文:
写一个函数,把字符串中所有的空格替换为%20 。
解答
简单题。
剑指offer中也提到了此题,在网络编程(服务器)中,URL中含有特殊字符 如 空格 ‘#’ 服务器端无法获取正确的参数。所以要替换为相应ascii码的十六进制1. Count the number of spaces during the first scan of the string.
2. Parse the string again from the end and for each character:
»»If a space is encountered, store “%20”.
»»Else, store the character as it is in the newly shifted location.
#include <iostream>using namespace std;void replaceBlank(char* str){if (str == NULL) return;int count = 0,len = strlen(str);for (int i = 0; i < len; i++){if (str[i] == ' '){count++;}}int size = len + 2*count;str[size] = '\0';int start = 0,end = size - 1;for (int j = len - 1; j >= 0; j--){if (str[j] == ' '){str[end] = '0';str[end - 1] = '2';str[end - 2] = '%';end -= 3;}else{str[end--] = str[j];}}}int main(){ char a[20] = "a b c d"; replaceBlank(a); cout<<a<<endl; return 0;}
1.6
Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place?
译文:
一张图像表示成NxN的矩阵,图像中每个像素是4个字节,写一个函数把图像旋转90度。 你能原地进行操作吗?(即不开辟额外的存储空间)
解答
#include <iostream>using namespace std;void rotate90(int a[][4],int n){for (int layer = 0; layer < n / 2; ++layer) { int first = layer; int last = n - 1 - layer; for(int i = first; i < last; ++i) { int offset = i - first; int top = a[first][i]; // save top // left -> top a[first][i] = a[last-offset][first]; // bottom -> left a[last-offset][first] = a[last][last - offset]; // right -> bottom a[last][last - offset] = a[i][last]; // top -> right a[i][last] = top; // right <- saved top } }for(int i=0; i<4; ++i){for(int j=0; j<4; ++j)cout<<a[i][j]<<" ";cout<<endl;}cout<<endl;;}int main(){int a[][4] = {1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16};rotate90(a,4);return 0;}
1.7
Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.
译文:
写一个函数处理一个MxN的矩阵,如果矩阵中某个元素为0,那么把它所在的行和列都置为0.
解答
简单题。
At first glance, this problem seems easy: just iterate through the matrix and every time we see a 0, set that row and column to 0. There’s one problem with that solution though: we will “recognize” those 0s later on in our iteration and then set their row and column to zero. Pretty soon, our entire matrix is 0s!
One way around this is to keep a second matrix which flags the 0 locations. We would then do a second pass through the matrix to set the zeros. This would take O(MN) space.
Do we really need O(MN) space? No. Since we’re going to set the entire row and column to zero, do we really need to track which cell in a row is zero? No. We only need to know that row 2, for example, has a zero.
The code below implement this algorithm. We keep track in two arrays all the rows with zeros and all the columns with zeros. We then make a second pass of the matrix and set a cell to zero if its row or column is zero.
一个变通的方法,在另外一个MxN的矩阵中记录是否出现零的情况,然后根据记录对原来的矩阵中对相应的行列进行置零。可是这样方法的空间复杂度为O(MxN)。有没有改进的空间呢?
经过观察,其实我们只需要记录哪一列和哪一行需要置零即可。那么我们新的记录方法即为:使用两个数组rows[]和col[]来记录需要置零的行列。更具这样的方法算法代码如下:
#include <iostream>using namespace std;void setZeros(int (*a)[4],int m,int n){ bool* row = new bool[m],*col = new bool[n]; memset(row,0,sizeof(row)); memset(col,0,sizeof(col)); // Store the row and column index with value 0 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (a[i][j] == 0) { row[i] = true; col[j] = true; } } } // Set arr[i][j] to 0 if either row i or column j has a 0 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (row[i]||col[j]) { a[i][j] = 0; } } } delete row; delete col;}int main(){int a[][4] = {1,2,3,2, 4,5,6,7, 8,9,0,4, 3,5,2,3};for(int i=0; i<4; ++i){for(int j=0; j<4; ++j)cout<<a[i][j]<<" ";cout<<endl;}cout<<endl; setZeros(a,4,4);for(int i=0; i<4; ++i){for(int j=0; j<4; ++j)cout<<a[i][j]<<" ";cout<<endl;}cout<<endl;return 0;}
1.8
Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring (i.e., “waterbottle” is a rotation of “erbottlewat”).
译文:
假设你有一个isSubstring函数,可以检测一个字符串是否是另一个字符串的子串。 给出字符串s1和s2,只使用一次isSubstring就能判断s2是否是s1的旋转字符串, 请写出代码。旋转字符串:"waterbottle"是"erbottlewat"的旋转字符串。
解答
Just do the following checks
1. Check if length(s1) == length(s2). If not, return false.
2. Else, concatenate s1 with itself and see whether s2 is substring of the result.
input: s1 = apple, s2 = pleap ==> apple is a substring of pleappleap
input: s1 = apple, s2 = ppale ==> apple is not a substring of ppaleppale
很巧妙的算法:
算法描述:
1 如果length(s1)!= length(s2) 返回 false
2 将是s1和本身连接,得到新字符串s1',调用isSubstring(s2,s1')判断s2是否为s1'的字符串。
#include <iostream>#include <string>using namespace std;bool isSubstring(string s1, string s2){if(s1.find(s2) != string::npos) return true;else return false;}bool isRotation(string s1, string s2){if(s1.length() != s2.length() || s1.length()<=0)return false;return isSubstring(s1+s1, s2);}int main(){string s1 = "apple";string s2 = "pleap";cout<<isRotation(s1, s2)<<endl;//cout<<string::npos<<endl;return 0;}
- Solutions to Chapter 1 | Arrays and Strings
- Chapter 1 Arrays and Strings
- Chapter 1 Arrays and Strings - 1.1
- Chapter 1 Arrays and Strings - 1.2
- Chapter 1 Arrays and Strings - 1.3
- Chapter 1 Arrays and Strings - 1.4
- Chapter 1 Arrays and Strings - 1.5
- Chapter 1 Arrays and Strings - 1.6
- Chapter 1 Arrays and Strings - 1.7
- Chapter 1 Arrays and Strings - 1.8
- CareerCup chapter 1 Arrays and Strings
- [CC150] Chapter 1 Arrays and Strings
- CC150 chapter 1 Arrays and strings.
- Chapter 1 | Arrays and Strings -- 判断字符串中字符唯一
- Chapter 1 | Arrays and Strings--旋转字符串的判断
- Chapter 3. Strings, Vectors, and Arrays
- Arrays and Strings----1
- Chapter 1 | Arrays and Strings--字符串的翻转与去重
- ORACLE函数大全
- 关于SQL 数据库表中的聚集索引和非聚集索引等
- 贴片电阻封装与功率
- 未能加载文件或程序集“DAL”或其他的某一个依赖项,系统找不到指定的文件
- 杭电2158-最短区间版大家来找碴
- Solutions to Chapter 1 | Arrays and Strings
- 【水一发next_permutation】poj 1146——ID Codesm
- spring security1
- VC 多线程异步方式操作串口
- UITextField align left margin
- hive中简单介绍分区表
- 使用poi进行excel比对程序
- opencv2 矩阵方式 resize图像缩放代码及cvresize函数用法
- Dijkstra,Ford,SPF,Floyd,Johnson