51构建乘积数组
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]* A[1]* …* A[i-1]* A[i+1]*…*A[n-1]。不能使用除法。
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
vector<int> b;
for(int i=0;i<A.size();i++){
b.push_back(1);
for(int j=0;j<A.size();j++){
if(j!=i){
b[i]*=A[j];
}
}
}
return b;
}
};
52正则表达式匹配
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
class Solution {
public:
bool match(char* str, char* pattern){
if(str==nullptr || pattern==nullptr)return false;
return matchCore(str,pattern);
}
bool matchCore(char *str,char *pattern)
if(*str=='\0' && *pattern=='\0')return true;
if(*str!='\0' && *pattern=='\0')return false;
if(*(pattern+1)=='*'){
if(*str==*pattern || (*pattern=='.' && *str!='\0'))
return matchCore(str+1,pattern+2)||matchCore(str+1,pattern)||matchCore(str,pattern+2);
else
return matchCore(str,pattern+2);
}
if(*str==*pattern || (*pattern=='.' && *str!='\0'))
return matchCore(str+1,pattern+1);
return false;
}
};
/*
思路
如果模式串此时是'.',那么只需要模式串与匹配串都往后移动一个位置即可
如果现在这位的字符能匹配且且模式串的下一位是'*',我们则需要分情况讨论
1.匹配串往后移动1位,模式串跳过'*'
2.匹配串往后移动1位,模式串不动
3.匹配串不动,模式串跳过'*'
*/
53表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
class Solution {
public:
bool isNumeric(char* string){
int dotIdx=0;//first find dot
for(int i=0;string[i]!='\0';i++){
if(string[i]=='.'){
if(dotIdx!=0)return false;
dotIdx=i;
}
}
int flag=0;//e flag
for(int i=0;string[i]!='\0';i++){
//cout<<string[i]<<endl;
if(i==0 && string[i]=='+')continue;
if(i==0 && string[i]=='-')continue;
if(string[i]=='E' || string[i]=='e'){
flag++;
if( flag==2 || i<dotIdx )return false;
if( string[i+1]=='+' || string[i+1]=='-')i++;
if( string[i+1]<'0' || string[i+1]>'9' )return false;
else continue;
}
if(string[i]>='0' && string[i]<='9')continue;
if(string[i]=='.')continue;
return false;
}
return true;
}
};
54字符流中第一个不重复的字符
题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
class Solution
{
public:
//Insert one char from stringstream
vector<char> let;
vector<int> num;
void Insert(char ch)
{
for(int i=0;i<let.size();i++){
if(let[i]==ch){
num[i]++;
return ;
}
}
let.push_back(ch);
num.push_back(1);
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce(){
for(int i=0;i<num.size();i++){
if(num[i]==1){
return let[i];
}
}
return '#';
}
};
55链表中环的入口结点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
set<ListNode*> s;
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode* p=pHead;
while(p!=NULL){
if(s.find(p)!=s.end()){
return p;
}
s.insert(p);
p=p->next;
}
return NULL;
}
};
56删除链表中重复的结点
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead){
if (pHead == NULL)return NULL; // 先判断空
if (pHead->next == NULL)return pHead; // 判断是否只有一个节点
ListNode* pre = new ListNode(int()); // 我们采用带头链表,自己添加一个头
pre->next = pHead; // 把头节点链接在链表上
ListNode* pre_head = pre; // 用来保存头节点,用于返回删除后的链表
ListNode* cur = pHead; //中指针
ListNode* nex = pHead->next; // 后面指针
while (nex != NULL){ // 结束条件
while (nex != NULL && cur->val == nex->val)nex = nex->next;
// 当NEX跳到空,或者与中指针值不同时就是进入下面的判断
if (cur->next != nex){ // 中针与后针不相邻则必定有重复
while (cur != nex){ // 把CUR一直后移,直到CUR是后针为止
pre->next = cur->next;//前针的后继指向中针的后继
cur = pre->next;//中针记为前针后继(结合上一句,不就是它自己的后继吗!)
}
if (nex != NULL) // 这里一定要要注意,要防止走到NULL发生段错误
nex = nex->next;//中针已经指向了后后,所以后针也要后移了
}
else{ //cur->next == nex 没有重复的情况,CUR点是要插入的
pre = cur; //前针后移
nex = nex->next; //后针后移
cur = cur->next; //中针后移
}
}
ListNode* head = pre_head->next; //自定义的头结点不是真正的起点
return head;//输出真正的头指针
}
};
57二叉树的下一个结点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==NULL)return NULL;
if(pNode->right!=NULL){
TreeLinkNode* p = pNode->right;
while(p->left!=NULL){
p=p->left;
}
return p;
}
if(pNode->right==NULL && pNode->next!=NULL && pNode==pNode->next->left)return pNode->next;
if(pNode->right==NULL && pNode->next!=NULL && pNode==pNode->next->right){
TreeLinkNode* p = pNode->next;
while( p->next!=NULL && p==p->next->right )p=p->next;
return p->next;
}
return NULL;
}
};
58对称的二叉树
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的
class Solution {
public:
bool dfs(TreeNode* p1,TreeNode* p2){
if(p1NULL && p2NULL)return true;//双空
if(p1NULL && p2!=NULL)return false;//右空
if(p2NULL && p1!=NULL)return false;//左空
if(p1->val != p2->val)return false;//值不等
return ( dfs(p1->left,p2->right) && dfs(p1->right,p2->left) );//判左儿与右儿
}
bool isSymmetrical(TreeNode* pRoot)
{
if(pRoot==NULL)return true;
return dfs(pRoot->left,pRoot->right);
}
};
59按之字形顺序打印二叉树
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > ans;
queue<TreeNode*> q1,q2;
void f1(){
while(!q2.empty())q2.pop();
vector<int>tmp;
while(!q1.empty()){
TreeNode* t=q1.front();
tmp.push_back(t->val);
q1.pop();
if(t->left!=NULL)q2.push(t->left);
if(t->right!=NULL)q2.push(t->right);
}
if(tmp.size()!=0)ans.push_back(tmp);
}
void f2(){
while(!q1.empty())q1.pop();
vector<int>tmp;
while(!q2.empty()){
TreeNode* t=q2.front();
tmp.push_back(t->val);
q2.pop();
if(t->left!=NULL)q1.push(t->left);
if(t->right!=NULL)q1.push(t->right);
}
if(tmp.size()!=0){
for(int x=0;x<tmp.size()/2;x++){
swap(tmp[x],tmp[tmp.size()-x-1]);
}
ans.push_back(tmp);
}
}
vector<vector<int> > Print(TreeNode* pRoot) {
if(pRoot==NULL)return ans;
q1.push(pRoot);
while(!q1.empty()||!q2.empty()){
f1();
f2();
}
return ans;
}
};
60把二叉树打印成多行
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > ans;
queue<TreeNode*> q1,q2;
void f1(){
while(!q2.empty())q2.pop();
vector<int>tmp;
while(!q1.empty()){
TreeNode* t=q1.front();
tmp.push_back(t->val);
q1.pop();
if(t->left!=NULL)q2.push(t->left);
if(t->right!=NULL)q2.push(t->right);
}
if(tmp.size()!=0)ans.push_back(tmp);
}
void f2(){
while(!q1.empty())q1.pop();
vector<int>tmp;
while(!q2.empty()){
TreeNode* t=q2.front();
tmp.push_back(t->val);
q2.pop();
if(t->left!=NULL)q1.push(t->left);
if(t->right!=NULL)q1.push(t->right);
}
if(tmp.size()!=0)ans.push_back(tmp);
}
vector<vector<int> > Print(TreeNode* pRoot) {
if(pRoot==NULL)return ans;
q1.push(pRoot);
while(!q1.empty()||!q2.empty()){
f1();
f2();
}
return ans;
}
};