面试算法题-01
2017-04-30 15:37
176 查看
1.在一个数组中找出有几个k,用O(log(n))算法实现
代码:
2.判断平衡二叉树
3.输入一个数组,其中有两个值是惟一的,其他都有两个,求这两个值,要求空间复杂度是O(1),时间复杂度O(n)
看了解答,觉得神他妈复杂,自己写了一个,试了几个例子,是对的
这里补一下答案的代码:
在一个数组里找两个数,这两个数的和是特定的值,要求时间为O(n),数组有序
代码:
给一个数n,从1-n中找出连续的串使得和为n,时间为O(n)
代码:
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如输入“I am a student.”,则输出“student. a am I”。
代码:空间复杂度高
空间复杂度低:
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串”abcdefg”和数字2,该函数将返回左旋转2位得到的结果”cdefgab”。
代码:
约瑟夫环路:
n个数从1-n形成一个环,每次删除环中的第m个数,求最后一个被删除的数
代码:
用位运算求两数相加:
代码:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<string> using namespace std; int arr[10]={2,3,3,3,3,4,5}; int first(int k) { int left=0, right=7; while(left<=right) { int mid = (left+right)>>1; if(arr[mid]>k) right=mid-1; else if(arr[mid]<k) left=mid+1; else { if(arr[mid-1]==k && mid>0) { right = mid-1; } else return mid; } } return -1; } int last(int k) { int left=0, right=7; while(left<=right) { int mid = (left+right)>>1; if(arr[mid]>k) right=mid-1; else if(arr[mid]<k) left=mid+1; else { if(arr[mid-1]==k && mid<right-1) { left = mid+1; } else return mid; } } return -1; } int main() { int f = first(3); int l = last(3); if(f!=-1 && l!=-1) { printf("%d\n", l-f+1); } else printf("can not found\n"); return 0; }
2.判断平衡二叉树
struct BinaryTreeNode { int m_valuel; BinaryTreeNode *m_lson; BinaryTreeNode *m_rson; }; //复杂度大于O(n),小于O(n^2) int GetDepth(BinaryTreeNode *root) { if(root == NULL) { return 0; } int l = GetDepth(root->m_lson); int r = GetDepth(root->m_rson); return l>r?l+1:r+1; } bool IsBalanced(BinaryTreeNode *root) { if(root == NULL) return true; int l = GetDepth(root->m_lson); int r = GetDepth(root->m_rson); int dis = r-l; if(dis>=-1 && dis<=1) { return IsBalanced(root->m_lson)&&IsBalanced(root->m_rson); } else return false; } //后序遍历,复杂度O(n) bool IsBalanced(BanaryTreeNode *root, int *depth) { if(root == NULL) { *depth=0; return true; } int l=0; int r=0; if(IsBalanced(root->m_lson,&l) && IsBalanced(root->m_rson,&r)) { int dis=l-r; if(dis>=-1 && dis<=1) { *depth=1+l>r?l:r; return true; } else return false; }else return false; }
3.输入一个数组,其中有两个值是惟一的,其他都有两个,求这两个值,要求空间复杂度是O(1),时间复杂度O(n)
看了解答,觉得神他妈复杂,自己写了一个,试了几个例子,是对的
#include<cstdio> #include<cstring> #include<algorithm> #include<string> using namespace std; int arr[8] = {2,4,3,5,3,2,5,6}; int main() { sort(arr,arr+8); int flag=0; for(int i=0; i<7;) { if(arr[i]!=arr[i+1]) { printf("%d\n",arr[i]); i++; flag++; } else { i+=2; } } if(flag != 2) printf("%d\n",arr[7]); }
这里补一下答案的代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<string> using namespace std; int arr[10]={2,4,4,6,3,2,5,5}; void FindNumAppearOnce(int n) { if(arr==NULL || n<2) return; int sum=0; for(int i=0; i<n; i++) { sum ^= arr[i]; } int pos = 0; while((sum&1)!=1 && (pos<32)) { pos++; sum >>= 1;//右移 } if(pos>=32) { return; } int one=0, two=0; int num=1<<pos; for(int i=0; i<n; i++) { if((arr[i]&num)!=0) { one ^= arr[i]; } else { two ^= arr[i]; } } printf("%d %d\n", one, two); } int main() { FindNumAppearOnce(8); return 0; }
在一个数组里找两个数,这两个数的和是特定的值,要求时间为O(n),数组有序
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<string> using namespace std; int arr[6] = {1,2,4,7,11,15}; int n = 6; bool Find(int s, int& num1, int& num2) { bool isFind = false; if(arr==NULL || n<=0) { return isFind; } int p1=0, p2=n-1; while(p1<p2) { int sum=arr[p1]+arr[p2]; if(sum == s) { isFind=true; num1=arr[p1],num2=arr[p2]; break; } else if(sum > s) { p2--; }else p1++; } return isFind; } int main() { int a, b; if(Find(15,a,b)) printf("%d %d\n", a, b); else printf("not found\n"); return 0; }
给一个数n,从1-n中找出连续的串使得和为n,时间为O(n)
代码:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<string> using namespace std; void print(int f, int t) { printf("%d", f); for(int i=f+1; i<=t; i++) printf(" %d", i); printf("\n"); } void FindSequenceSum(int s) { if(s<3) return; int start=1,end=2,sum=3; int mid=(s+1)>>1; while(start<mid) {//超过一半接下来加的就是比一半大的数了,不可能得到s if(s == sum) { print(start,end); end++; sum += end; }else if(sum>s) { sum -= start; start++; }else { end++; sum += end; } } } int main() { FindSequenceSum(9); return 0; }
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如输入“I am a student.”,则输出“student. a am I”。
代码:空间复杂度高
#include<cstdio> #include<algorithm> #include<cstring> #include<cstdio> #include<string> #include<cstring> #include<iostream> using namespace std; char str[105][100]; int main() { char s[105]; memset(str, 0, sizeof(str)); while(gets(s)) { int j = 0; for(int i=0; i<strlen(s);) { if(s[i]!=' ' && s[i] != '\n' && s[i] != '\0') { int z = 0; while(s[i]!=' ' && s[i] != '\n' && s[i] != '\0') { str[j][z] = s[i]; z++, i++; } str[j][z] = '\0'; j++; }else{ i++; } } printf("%s", str[j-1]); for(int i=j-2; i>=0; i--) printf(" %s", str[i]); printf("\n"); } return 0; }
空间复杂度低:
#include <iostream> #include<string> #include<cstdio> #include<cstring> using namespace std; void myReverse(char*, char*); char * senReverse(char*); int main() { char sen[]="hello, I am a student!"; char *result=senReverse(sen); cout << result << endl; return 0; } void myReverse(char *start, char* end) { char temp; while(start<end) { temp = *start; *start = *end; *end = temp; start++; end--; } } char * senReverse(char* sen) { char *start = sen, *end = sen+strlen(sen)-1; myReverse(start, end); end=start; while(*start != '\0') { if(*end==' '||*end=='\0') { myReverse(start,--end); if(*end=='\0') break; end+=2; start = end; }else ++end; } return sen; }
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串”abcdefg”和数字2,该函数将返回左旋转2位得到的结果”cdefgab”。
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> using namespace std; void ReverseWord(char* begin, char*end) { char temp; if(begin==NULL || end==NULL) { return; } while(begin<end) { temp = *begin; *begin = *end; *end = temp; begin++, end--; } } char* LeftRotateString(char* string, int k) { if(string==NULL || k<=0) return string; int len = (int)strlen(string); char* begin = string; char *end = string+len-1; if(k>len) return NULL; ReverseWord(begin, begin+k-1); ReverseWord(begin+k, end); ReverseWord(begin,end); return string; } int main() { char str[] = "abcdefg"; char *string = NULL; string = LeftRotateString(str,2); cout<<string<<endl; return 0; }
约瑟夫环路:
n个数从1-n形成一个环,每次删除环中的第m个数,求最后一个被删除的数
代码:
#include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<iostream> using namespace std; struct ListNode { int value; ListNode *nextNode; }; void BuildList(ListNode **headNode, int *arrNum, int n) { if(arrNum == NULL || n<=0) return; (*headNode)->value = arrNum[0]; (*headNode)->nextNode=NULL; ListNode *pre = (*headNode); for(int i=1; i<n; i++) { ListNode *newNode = new ListNode(); newNode->value = arrNum[i]; newNode->nextNode = NULL; pre->nextNode = newNode; pre = newNode; } pre->nextNode = *headNode; } int GetLastNum(ListNode *headNode, int n, int m) { /*if(headNode==NULL || n<=0 || m<=0) { throw exception("error"); }*/ int count=n; ListNode *pNode = headNode; while(count>1) { int pos = 1; while(pos<m-1) { ++pos; pNode=pNode->nextNode; } ListNode *tmpNode = pNode->nextNode; pNode->nextNode = tmpNode->nextNode; delete tmpNode; tmpNode = NULL; --count; pNode=pNode->nextNode; } return pNode->value; } void print(ListNode* headNode) { ListNode *pNode = headNode; cout<<pNode->value<<endl; pNode=pNode->nextNode; while(pNode!=headNode) { cout<<pNode->value<<endl; pNode=pNode->nextNode; } } int main() { int arrNum[] = {1,2,3,4,5}; ListNode *headNode = new ListNode(); BuildList(&headNode,arrNum,5); // print(headNode); int ans = GetLastNum(headNode, 5, 3); printf("%d\n", ans); return 0; }
用位运算求两数相加:
#include<cstdio> #include<algorithm> #include<cstring> #include<string> using namespace std; int GetSum(int num1, int num2) { while(num2 != 0) { int sum = num1^num2; int carry = (num1&num2)<<1; num1=sum; num2=carry; } return num1; } int GetSum2(int num1, int num2) { if(num2==0) return num1; int sum = num1^num2; num2 = (num2&num1)<<1; num1 = sum; GetSum(num1, num2); } int main() { int ans = GetSum2(5,6); printf("%d\n", ans); return 0; }
相关文章推荐
- 面试-算法01
- 前端开发面试笔试学习--算法01--数组求和/数组去重
- 面试笔试算法系列之分治法
- 机器学习常见算法个人总结(面试用)
- 分享Java面试中遇到的一些经典算法题目
- 《微软等数据结构+算法面试100题》自娱自解(完结)
- 面试常见算法
- 代码面试最常用的10大算法
- 玩转算法面试-数据规模,时间复杂度,均摊复杂度
- 图像算法面试
- Android面试练习题(01)
- 常见面试算法小题目分享~更新ing~
- Java面试常见算法
- 珍藏版、微软等数据结构+算法面试100题全部出炉
- 前端js面试中的常见的算法问题
- 经典面试问题:12小球问题算法(文档)
- [玩转算法面试]什么是算法面试?
- 编程面试的10大算法概念汇总
- 经典面试问题:12小球问题算法(抄的)
- 10个经典的C语言面试基础算法及代码