一.2012
遇到的问题:1.两个链表的长度不同时,遍历的位置不同步
算法思路:1.求出两个链表的长度m和n
2.让p,q分别指向两个链表的头结点,如果m>n则让p移动到m-n+1的位置;如果m<n则让q移动到m-n+1的位置,这样两个指针的移动就可以同步了。
3.反复让p,q指针同步往后移动,并判断是否指向同一结点,若是,则该结点就是两个链表的共同后缀起始位置。
4.时间复杂度:o(m+n)
//求解链表长度
int length(Linklist L){
int i=0;
LNode *p = L->next;
while(p!=NULL){
p=p->next
++i;
}
return i;
}
//查找位置
Linklist find(Linklist str1,Linklist str2){
int len1=length(str1), len2=length(str2);
LNode *p,*q;
//使链表等长
for(p=str1; len1>len2; len1--)
p=p->next;
for(q=str2; len1<len2; len2--)
q=q->next;
//注意此时p,q后面的长度相等,所以p不空则q不空
while(p->next!=NULL && p-next !=q->next){
//两指针同步后移
p=p->next;
q=q->next;
}
}
二.2013
1.暴力解法(虚拟数组)10分
注意:0<=元素<n
思路:1.用虚拟数组表示A中元素出现的次数,比如A数组:0 1 2 3
值:2 3 2 1
则虚拟数组 :0 1 2 3
值(表示个数): 0 1 2 1
2.观察虚拟数组中的值是否大于n/2
//int find(Sqlist &A) //传顺序表不用定义n,长度直接A.length,元素用A.data[i]
//传数组,n表示数组长度,元素A[i]
int find(A[],int n) {
int *B=(int *)malloc(sizeof(int)*n);
int max=0, p; //p表示元素的位置
for(int i=0;i<n;++i){
//虚拟数组初值赋0
B[i]=0;
}
//遍历A数组,将元素个数存入B
for(int j=0;j<n;++j){
B[A[j]]++
}
//找B中元素最大值,再判断是否大于n/2
for(int k=0;k<n;++k){//n表示数组长度,遍历数组
if(max<B[K])
max=B[K];
p=k;
}
//判断
if(max>n/2) return p;//p代表数组B中的位置,B中的位置在A中表示元素值
else return -1;
}
三.2014
注意:考察树和图一般比较简单(考递归比较多)
1.只有叶子结点才有带权路径长度
2.带权路径长度=左子树的+右子树的
3.时间复杂度o(n) 空间复杂度o(n)-----递归用到栈
//定义树的结构体
typedef struct BTNode{
int weight;
struct BTNode *left,*right;
}BTNode;
int fun(BTNode *root,int deep){//要传深度
int A,B;
//递归的一个出口(必须写)
if (root==NULL) return 0;
//找叶子结点并求权重
if(root->left==null && root->right==null)
return (root->weight)*deep;
//左右子树递归
A=fun(root->left,deep+1) //注意deep要加一
B=fun(root->right,deep+1)
return A+B;
}
//主函数
void main(BTNode *root){
int fun(root,0); //给deep赋初值
}
四.2015
注意:1.出现“时间复杂度尽可能高效”,要考虑空间换时间(虚拟数组)
1.暴力解
重点:1.设置两个指针,两层循环 ;
2.删除结点的时候找到前一个结点指针 ;
3.一定要把 p->link !=NULL 放在外层循环,因为q是随着p而改变的
4. 时间复杂度o(n^2) 空间复杂度o(1)
//返回绝对值
int ads(LNode *p){
if(p->data >=0)
return p->data;
else
return -p->data;
}
//删除绝对值相同的元素
void delete(LNode *&L){//链表改变了要加 &
LNode *p=L; //把头结点赋给p
while(p->link !=NULL){
LNode *q=p->link; //第一个结点赋给q
while(q->link !=NULL){
//第一个结点等于第二个节点
if(abs(p->link) == abs(q->link)) {
LNode *r=q->link; //令r指向q后面的元素
q->link=r->link;
free(r);
}else{ q->link; }
}
p=p->link;
}
}
2.最优解(虚拟数组)
注意:1.data<=n ,所以数组的大小为n+1(数组从0开始)
2.依次扫描单链表中的元素,对应值出现一次,则令值所对应位置上的元素为1,若第二次扫描到相同结点,会发现虚拟数组对应位置为1,则删除该链表元素。
3.时间复杂度o(n) 空间复杂度o(n)
void fun(LNode *L,int n){
LNode *p=L;
int m;
int *q=(int *)malloc(sizeof(int)*(n+1));
for(int i=o;i<n+1;i++)
q[i]=0; //虚拟数组赋初值
while(p->link !=NULL){
m=p->link->data >0 ? p->link->data : -p->link->data;
//首次出现
if(q[m]==0) { q[m]=1; p=p->link; }
else{//删除
LNode *r=p->link;
p->link=r->link;
free(r);
}
}
free(q);
}