目录
1.剑指Offer
面试题23:链表环中的入口节点
题目描述:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:1.确定是否有环,用快慢指针,若有则找到环中任意一个节点
2.利用环中任意一个节点,确定环中节点的数目
3.找到环的入口节点
代码:
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode* meetingNode=MeetingNode(pHead);
if(meetingNode==nullptr) return nullptr;
int numNodeOfLoop=1;
ListNode* pNode=meetingNode->next;
while(pNode!=meetingNode){
pNode=pNode->next;
numNodeOfLoop++; //找到环中的节点数目
}
ListNode* pNode1=pHead;
for(int i=0;i<numNodeOfLoop;i++){
pNode1=pNode1->next;
}
ListNode* pNode2=pHead;
while(pNode1!=pNode2){ //找到环的入口节点
pNode1=pNode1->next;
pNode2=pNode2->next;
}
return pNode1;
}
ListNode* MeetingNode(ListNode* pHead){ //找到环中任意一个节点
if(pHead==nullptr) return nullptr;
ListNode* pSlow=pHead->next;
if(pSlow==nullptr){
return nullptr;
}
ListNode* pFast=pSlow->next;
while(pFast!=nullptr&&pSlow!=nullptr){
if(pFast==pSlow){
return pFast;
}
pSlow=pSlow->next;
pFast=pFast->next;
if(pFast!=nullptr){
pFast=pFast->next;
}
}
return nullptr;
}
};
面试题65:不用加减乘除做加法
题目描述:写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
思路:位运算,分三步:
1.不考虑进位,对每一位相加,相当于做异或
2.考虑进位,相当于对每位先做位与,再左移一位
3.把前两步的结果累加,相当于重复直到不产生进位
代码:
class Solution {
public:
int Add(int num1, int num2)
{
int sum=0;
int carry=0;
do{
sum=num1^num2;
carry=(num1&num2)<<1;
num1=sum;
num2=carry;
}while(num2!=0);
return num1;
}
};
2.Leetcode
例1:恢复二叉搜索树
题目描述:
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n ) space is pretty straight forward. Could you devise a constant space solution?
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
1
/ \
2 3
/
4
\
5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
思路:中序遍历
代码:
class Solution {
public:
TreeNode *pre,*a,*b;
void recoverTree(TreeNode *root) {
pre=a=b=NULL;
dfs(root);
if(a&&b) swap(a->val,b->val);
}
void dfs(TreeNode *root){
if(!root) return;
dfs(root->left);
if(pre&&pre->val>root->val){
if(!a) a=pre;
b=root;
}
pre=root;
dfs(root->right);
}
};
例2:判断是否为有效二叉搜索树
题目描述:
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than the node's key.
- Both the left and right subtrees must also be binary search trees.
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
1
/ \
2 3
/
4
\
5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
思路:每个结点都对应一个上限,一个下限。
代码:
class Solution {
public:
bool Solve(TreeNode *root, int low, int high){
if(root==NULL) return true;
if(root->val<=low||root->val>=high){
return false;
}
return Solve(root->left,low,root->val)&&Solve(root->right,root->val,high);
}
bool isValidBST(TreeNode *root) {
return Solve(root,INT_MIN,INT_MAX);
}
};
3.2017年腾讯秋招编程题
例1:[编程题] 编码
题目描述:
假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy 其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。 编写一个函数,输入是任意一个编码,输出这个编码对应的Index.
输入描述:
输入一个待编码的字符串,字符串长度小于等于100.
输出描述:
输出这个编码的index
输入例子1:
baca
输出例子1:
16331
思路:两层for循环,一层编码长度,一层当前位数,找规律发现该编码每次加n*25^j,n是当前位字母编码是第几个,j是当前位数的第几位。
代码:
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main(){
string str;
cin>>str;
int index=0;
int len=str.length();
for(int i=0;i<len;i++,index++){
int n=str[i]-'a';
for(int j=0;j<4-i;j++){
index+=n*pow(25,j);
}
}
cout<<index-1<<endl;
return 0;
}