80道常见数据结构面试题及其解法

【数据结构】面试题整理 共36题 链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和一个指向下一个节点的指针。与数组不同,链表中的元素在内存中不必是连续存储的,这使得链表在插入和删除操作时非常高效。单向链表(Singly Linked List):每个节点只包含一个指向下一个节点的指针。双向链表(Doubly Linked List):每个节点包含两个指针,一个指向下一个节点,一个指向前一个节点。循环链表(Circular Linked List):链表的最后一个节点指向第一个节点,形成一个环。 阅读详情

1.把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// 1:构造二叉查找树;
// 2:中序遍历二叉查找树,因此结点按从小到大顺序访问,假设之前访问过的结点已经调整为一个双向链表,那么
//       只需要将当前结点连接至双向链表的最后一个结点即可,访问完后,双向链表也就调整完了
#include <iostream>
using  namespace  std;
struct  BSTreeNode
{
     int  m_nValue;  // value of node
     BSTreeNode *m_pLeft;  // left child of node
     BSTreeNode *m_pRight;  // right child of node
};
 
void  addBSTreeNode(BSTreeNode *&pCurrent, int  value);
void  inOrderBSTree(BSTreeNode* pBSTree);
void  convertToDoubleList(BSTreeNode* pCurrent);
 
BSTreeNode *pHead=NULL; //指向循环队列头结点
BSTreeNode *pIndex=NULL; //指向前一个结点
 
int  main()
{
     BSTreeNode *pRoot=NULL;
     addBSTreeNode(pRoot,10);
     addBSTreeNode(pRoot,6);
     addBSTreeNode(pRoot,14);
     addBSTreeNode(pRoot,4);
     addBSTreeNode(pRoot,8);
     addBSTreeNode(pRoot,12);
     addBSTreeNode(pRoot,16);
     inOrderBSTree(pRoot);
     return  0;
}
/************************************************************************/
/* 建立二叉排序树                                                               */
void  addBSTreeNode(BSTreeNode *&pCurrent, int  value) //在这个函数中会要改变指针值,一定要记得使用引用传递
{
     if  (pCurrent==NULL)
     {
         BSTreeNode* pBSTree= new  BSTreeNode();
         pBSTree->m_nValue=value;
         pBSTree->m_pLeft=NULL;
         pBSTree->m_pRight=NULL;
         pCurrent=pBSTree;
     }
     else  if  (pCurrent->m_nValue<value)
     {
         addBSTreeNode(pCurrent->m_pRight,value);
     }
     else  if  (pCurrent->m_nValue>value)
     {
         addBSTreeNode(pCurrent->m_pLeft,value);
     }
     else
     {
         cout<< "node repeated" <<endl;
     }
 
}
/************************************************************************/
 
/************************************************************************/
/* 中序遍历二叉树,同时调整结点指针                                                                     */
void  inOrderBSTree(BSTreeNode* pBSTree)
{
 
     if  (NULL==pBSTree)
     {
         return ;
     }
     if  (NULL!=pBSTree->m_pLeft)
     {
         inOrderBSTree(pBSTree->m_pLeft);
     }
 
     //  if (NULL!=pBSTree)
     //  {
     //      cout<<pBSTree->m_nValue;
     //  }
     convertToDoubleList(pBSTree);
 
     if  (NULL!=pBSTree->m_pRight)
     {
         inOrderBSTree(pBSTree->m_pRight);
     }
 
}
/************************************************************************/
 
/************************************************************************/
/* 调整结点指针                                                                   */
void  convertToDoubleList(BSTreeNode* pCurrent)
{
     pCurrent->m_pLeft=pIndex; //使当前结点的左指针指向双向链表中最后一个结点
     if  (NULL==pIndex) //若最后一个元素不存在,此时双向链表尚未建立,因此将当前结点设为双向链表头结点
     {
         pHead=pCurrent;
     }
     else //使双向链表中最后一个结点的右指针指向当前结点
     {
         pIndex->m_pRight=pCurrent;
     }
 
     pIndex=pCurrent; //将当前结点设为双向链表中最后一个结点
 
     cout<<pCurrent->m_nValue<< " " ;
 
}
/************************************************************************/






2:

计包含min函数的栈

要求

定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素。 

要求函数min、push 以及pop 的时间复杂度都是O(1)。


解法

 

使用一个辅助栈来保存最小元素,这个解法简单不失优雅。设该辅助栈名字为minimum stack,其栈顶元素为当前栈中的最小元素。这意味着

 

  • 要获取当前栈中最小元素,只需要返回minimum stack的栈顶元素即可。
  • 每次执行push操作,检查push的元素是否小于或等于minimum stack栈顶元素。如果是,则也push该元素到minimum stack中。
  • 当执行pop操作的时候,检查pop的元素是否与当前最小值相等。如果相同,则需要将改元素从minimum stack中pop出去。
struct minStack{
    stack<int> s;
    stack<int> minS;

    void push(int i){
        if (s.empty() || minS.empty()){
            s.push(i);
            minS.push(i);
        }else{
            if (minS.top() >= i){
                minS.push(i);
            }
            s.push(i);
        }
    }

    void pop(){
        if (s.empty() || minS.empty()){
            return;
        }
        if (s.top() > minS.top()){
            s.pop();
        }else{
            s.pop();
            minS.pop();
        }
    }

    int min(){
        if (minS.empty())
            return -1;
        else 
            return minS.top();
    }
};

 

3:题目:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。

一种从前往后遍历的方法如下:

[cpp]  view plain  copy
  1. // 需要保存起始点与结束点下标的时候,从前往后遍历也是可以的  
  2. int MaxSum(int *a , int n)  
  3. {  
  4.     int tempstart = 0 , sum=0 , max = -1000;  
  5.     int i , start , end;  
  6.     start = end = 0;  
  7.     for(i = 0 ; i < n ; ++i)  
  8.     {  
  9.         if(sum < 0)  
  10.         {  
  11.             sum = a[i];  
  12.             tempstart = i;  
  13.         }  
  14.         else  
  15.             sum += a[i];  
  16.         if(sum > max)  
  17.         {  
  18.             max = sum;  
  19.             start = tempstart;  
  20.             end = i;  
  21.         }  
  22.     }  
  23.     return max;  
  24. }  


4 面试题目:

        输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。
        例如输入整数 22 ,如下图二元树:
                                            10
                                           /     \
                                          5     12
                                        /    \   
                                       4     7 

   则打印出两条路径:10, 12和10, 5, 7。


思路:对于如图所示的二叉树,其实就是一个递归的过程,上例可以有三条路径10 5 4 ,10 5 7,10 12,递归调用者三次路径即可,如果满足就打印出来,不可以就再重复递归
代码如下:

  1. #include <iostream>  
  2. #include <vector>  
  3. using namespace std;  
  4.   
  5. struct BinaryTreeNode // a node in the binary tree  
  6. {  
  7.     int m_nValue; // value of node  
  8.     BinaryTreeNode *m_pLeft; // left child of node  
  9.     BinaryTreeNode *m_pRight; // right child of node  
  10. };  
  11.   
  12. vector<BinaryTreeNode*> pathVec;  
  13.   
  14. void creatTree(BinaryTreeNode *&root, int *a, int i, int len)  
  15. {  
  16.     if(i >= len)  
  17.         return;  
  18.     root = new BinaryTreeNode;  
  19.     root->m_nValue = a[i];  
  20.     root->m_pLeft = NULL;  
  21.     root->m_pRight = NULL;  
  22.     creatTree(root->m_pLeft, a, 2*i + 1, len);  
  23.     creatTree(root->m_pRight, a, 2*i + 2, len);  
  24. }  
  25.   
  26. void preorder(BinaryTreeNode* &root)  
  27. {  
  28.     if(!root)  
  29.         return;  
  30.     cout << root->m_nValue << " ";  
  31.     preorder(root->m_pLeft);  
  32.     preorder(root->m_pRight);      
  33. }  
  34.   
  35. void printPath(vector<BinaryTreeNode*>& pathVec)  
  36. {  
  37.     for(vector<BinaryTreeNode*>::iterator it = pathVec.begin(); it != pathVec.end(); it++)  
  38.         cout << (*it)->m_nValue << " ";  
  39.     cout << endl;  
  40. }  
  41.   
  42. void pathTree(BinaryTreeNode* &root, int val)  
  43. {  
  44. //输出二叉树中路径等于val的所有路径  
  45.     static int sum = 0;  
  46.     sum += root->m_nValue;  
  47.     pathVec.push_back(root);  
  48.     if(sum == val && root->m_pLeft == NULL && root->m_pRight == NULL)  
  49.         printPath(pathVec);  
  50.     if(root->m_pLeft)  
  51.         pathTree(root->m_pLeft, val);  
  52.     if(root->m_pRight)  
  53.         pathTree(root->m_pRight, val);  
  54.     sum -= root->m_nValue;  
  55.     pathVec.pop_back();  
  56. }  
  57.   
  58. int main()  
  59. {  
  60.     BinaryTreeNode *root = 0;  
  61.     int a[] = {10, 5, 12, 7, 8};  
  62.     int len = sizeof a / sizeof a[0];  
  63.     creatTree(root, a, 0, len);  
  64. //  preorder(root);  
  65.     pathTree(root, 22);  
  66. } 



需要注意的是出栈与入栈的处理,友情是这一步   sum -= root->m_nValue; 






5:题目是:输入n 个整数,输出其中最小的k 个。例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 和4。

问题分析:先用冒泡排序法将数列排序,然后输出其中最小的k个数,注意输入输出格式问题(空格问题)

代码:

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. void sort(int a[],int n,int k)  
  4. {  
  5.     int i=0,j=0;  
  6.     int temp;  
  7.     if(k>n)  
  8.     {  
  9.         cout<<"error"<<"\n";  
  10.     }  
  11.     else  
  12.     {  
  13.         for(i=0;i<n-1;i++)  
  14.             for(j=0;j<n-i-1;j++)  
  15.             {  
  16.                 if(a[j]>a[j+1])  
  17.                 {  
  18.                     temp=a[j];  
  19.                     a[j]=a[j+1];  
  20.                     a[j+1]=temp;  
  21.                 }  
  22.             }  
  23.             for(i=0;i<k-1;i++)  
  24.             {  
  25.                 cout<<a[i]<<" ";  
  26.             }  
  27.             cout<<a[k-1]<<"\n";  
  28.     }  
  29.       
  30. }  
  31. int main()  
  32. {  
  33.     int n;//输入整数个数  
  34.     int k;//输出最小的k个数  
  35.     cin>>n>>k;  
  36.     int a[100];  
  37.     int i=0;  
  38.     for(i=0;i<n;i++)  
  39.         cin>>a[i];  
  40.     sort(a,n,k);  
  41.     return 0;  
  42. }  

6.判断单链表是否有环

方法:使用p、q两个指针,p每次向前走一步,q每次向前走两步,若在某个时候p == q,则存在环。

#include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #define LEN 8
 5 typedef struct node* node_t;
 6 
 7 struct node{  
 8     char val;  
 9     struct node *next;  
10 };  
11 
12 //method 1
13 int has_loop(struct node *head);
14 //method 2
15 int has_loop2(node_t head);
16 
17 int main()
18 {
19     node_t* arr = (node_t*)malloc(sizeof(struct node)*LEN);
20     arr[0] = (node_t)malloc(sizeof(struct node));
21     int i;
22     for(i = 1; i < LEN; i++)
23     {
24         arr[i] = (node_t)malloc(sizeof(struct node));
25         arr[i - 1]->next = arr[i];
26     }
27     arr[LEN - 1]->next = NULL;
28 
29     //you can add a loop here to test
30     //arr[6]->next = arr[0];
31     if (has_loop(arr[0]))
32         printf("method1: has loop.\n");
33     else
34         printf("method1: has no loop.\n");
35 
36     if (has_loop2(arr[0]))
37         printf("method2: has loop.\n");
38     else
39         printf("method2: has no loop.\n");
40 
41     return 0;
42 }
43 
44 //if two pointer are equal, but they don't have the same steps, then has a loop
45 int has_loop(node_t head)  
46 {  
47     node_t cur1 = head;  
48     int pos1 = 0;  
49     while(cur1){  
50         node_t cur2 = head;  
51         int pos2 = 0;  
52         pos1 ++;  
53         while(cur2){  
54             pos2 ++;  
55             if(cur2 == cur1){  
56                 if(pos1 == pos2)  
57                     break;  
58                 else  
59                     return 1;
60             }  
61             cur2 = cur2->next;  
62         }  
63         cur1 = cur1->next;  
64     }  
65     return 0;  
66 } 
67 
68 //using step1 and step2 here 
69 //if exists a loop, then the pointer which use step2 will catch up with the pointer which uses step1
70 int has_loop2(node_t head)
71 {
72     node_t p = head;
73     node_t q = head;
74     while (p != NULL && q != NULL)
75     {
76         /*
77         p = p->next;
78         if (q->next != NULL)
79             q = q->next->next;
80         if (p == q)
81             return 1;
82             */
83         //correct it on 17/11/2012
84         p = p->next;
85         q = q->next;
86         if (q != NULL)
87             q = q->next;
88         if (p != NULL && p == q)
89             return 1;
90     }
91     return 0;
92 }
复制代码


第7题
微软亚院之编程判断俩个链表是否相交

一个比较经典的问题,判断两个链表是否相交,如果相交找出他们的交点。

image

思路:

1、碰到这个问题,第一印象是采用hash来判断,将两个链表的节点进行hash,然后判断出节点,这种想法当然是可以的。

2、当然采用暴力的方法也是可以的,遍历两个链表,在遍历的过程中进行比较,看节点是否相同。

3、第三种思路是比较奇特的,在编程之美上看到的。先遍历第一个链表到他的尾部,然后将尾部的next指针指向第二个链表(尾部指针的next本来指向的是null)。这样两个链表就合成了一个链表,判断原来的两个链表是否相交也就转变成了判断新的链表是否有环的问题了:即判断单链表是否有环?

这样进行转换后就可以从链表头部进行判断了,其实并不用。通过简单的了解我们就很容易知道,如果新链表是有环的,那么原来第二个链表的头部一定在环上。因此我们就可以从第二个链表的头部进行遍历的,从而减少了时间复杂度(减少的时间复杂度是第一个链表的长度)。

下图是一个简单的演示:

image

这种方法可以判断两个链表是否相交,但不太容易找出他们的交点。

4、仔细研究两个链表,如果他们相交的话,那么他们最后的一个节点一定是相同的,否则是不相交的。因此判断两个链表是否相交就很简单了,分别遍历到两个链表的尾部,然后判断他们是否相同,如果相同,则相交;否则不相交。示意图如下:

image

判断出两个链表相交后就是判断他们的交点了。假设第一个链表长度为len1,第二个问len2,然后找出长度较长的,让长度较长的链表指针向后移动|len1 - len2| (len1-len2的绝对值),然后在开始遍历两个链表,判断节点是否相同即可。

下面给出一个简单的实现:

typedef struct node_t

{

int data;//data

struct node_t *next; //next

}node;

 

node* find_node(node *head1, node *head2)

{

if(NULL == head1 || NULL == head2)

{

return NULL;//如果有为空的链表,肯定是不相交的

}

node *p1, *p2;

p1 = head1;

p2 = head2;

int len1 = 0;

int len2 =0;

int diff = 0;

while(NULL != p1->next)

{

p1 = p1->next;

len1++;

}

while(NULL != p2->next)

{

p2 = p2->next;

len2++;

}

if(p1 != p2) //如果最后一个节点不相同,返回NULL

{

return NULL;

}

diff = abs(len1 - len2);

if(len1 > len2)

{

p1 = head1;

p2 = head2;

}

else

{

p1 = head2;

p2 = head1;

}

for(int i=0; i<diff; i++)

{

p1 = p1->next;

}

while(p1 != p2)

{

p1 = p1->next;

p2 = p2->next;

}

return p1;

}

通过上面的操作就可以找到两个链表的交点了。







点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. //定义链表的节点。
  5. struct Link {
  6.     Link* next;
  7.     int value;
  8. };

  9. //递归方式:逆转单向链表
  10. Link* reverse1(Link *head) 
  11. {
  12.     if(head == NULL ) return NULL;
  13.     if(head->next == NULL) return head;
  14.  
  15.     Link* tail = NULL;
  16.     Link* temp = head->next;
  17.     tail = reverse1(head->next);
  18.     temp->next = head;
  19.     head->next = NULL;
  20.     return tail;
  21. }
  22. //非递归方式:逆转单向链表 
  23. void reverse(Link **head) 
  24. {
  25.     if(!head || !(*head)) return;
  26.     Link *pre, *cur, *nex;
  27.     pre = NULL, cur=*head;
  28.     while(cur) {
  29.         nex = cur -> next;
  30.         cur->next = pre;
  31.         pre = cur;
  32.         cur = nex;
  33.     }
  34.     *head = pre;
  35. }

  36. //输出整个链表
  37. void printLink(Link *head)
  38. {
  39.     Link *curr = head;
  40.     while(curr) {
  41.         printf("%d ", curr->value);
  42.         curr = curr->next;
  43.     }
  44.     printf("\n");
  45. }

  46. int main(void)
  47. {
  48.     Link *head, *p[10], *newhead;
  49.     int num = 10;
  50.     for(int i=0; i<num; i++) {
  51.         p[i] = new Link();
  52.         p[i]->next = NULL;
  53.         p[i]->value = i+1;
  54.         if (i==0) head = p[i];
  55.         else p[i-1]->next = p[i];
  56.     }
  57.     printLink(head);
  58.     reverse(&head);
  59.     printLink(head);
  60.     for(int i=0; i<num; i++) delete p[i];
  61.     system("pause");
  62. }

9:

整数序列是不是二元查找树的后序遍历结果

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。如果是返回true,否则返回false。

例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:

         8
       /  \
      6    10
    / \    / \
   5   7   9  11

因此返回true。

如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。

树的题目一般都是递归的思路,因为是因为是排序树,而且是后序,所以思路是序列最后一个必是根节点,从前往后遍历,比根节点小的都是其左子树,并且位于序列的左半部分,比其大的为其右子树,应该位于其右半部分。左右子树按上述思路分别进行判断。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
using  namespace  std;
void  test( const  int  data[], int  start, int  node, bool  &flag){
     if (flag&&start<node){        // 判断条件,注意start<node
         int  left=start;
         while (data[node]>data[left]){   //取得其左子树
             left++;                      
         }
         for ( int  j=left;j<node;j++){       //判断是否为其右子树
             if (data[j]<data[node]) {flag= false ; return ;} //若
         }
         test(data,0,left-1,flag);           //递归
         test(data,left,node-1,flag);
     }
}
int  main( void ){
     bool  flag= true ;
     int  a[]={5,7,6,9,11,10,8};
     test(a,0,6,flag);
     if (flag) cout<< "yes" <<endl;
     else  cout<< "no" <<endl;
     int  b[]={7,4,6,5};
     test(b,0,3,flag);
     if (flag) cout<< "yes" <<endl;
     else  cout<< "no" <<endl;
     system ( "pause" );
     return  0;
}

二元查找树的定义为:

(1)若左子树不空,则左子树上所有节点的值均小于其根节点的值。

(2)若右子树不空,则右子树上所有节点的值均小于其跟节点的值

(3)其左右子树也均为二叉查找树。

那么先给定一个数字序列5、7、6、9、11、10、8,判断这个序列是否是二元查找树的后根遍历。可以回想一下后序遍历的性质,先访问左子树,然后访问右子树,最后访问根节点。结合以上这些性质,就可以理解到,应该从给定序列的最后一个元素开始,最后一个元素设定为根节点,循环遍历一次数组,找左右子树的分界点,上面这个例子就是6,9之间。这样可以判断,5、6、7,这三个数为以8为根节点的左子树上的节点,9、11、10为以8为根节点的右子树的根节点。如果在对以上分出来的两个数组做同样的操作,那么就可以解决这个问题。综上所述,可以应用递归方法,递归的关键是找到结束的条件。下面给出代码,并进行两组测试。

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<assert.h>  
  3. int verify_is_post(int *s,int length)  
  4. {  
  5.     assert(s!=NULL);  
  6.     assert(length>0);  
  7.     int i,j;  
  8.     int root=s[length-1];  
  9.     for(i=0;i<length-1;i++)  
  10.     {  
  11.         if(s[i]>root)  
  12.             break;  
  13.     }  
  14.     for(j=i;j<length-1;j++)  
  15.     {  
  16.         if(s[j]<root)  
  17.             return 0;  
  18.     }  
  19.     int left=1;  
  20.     if(i>0)  
  21.     {  
  22.         left=verify_is_post(s,i);//分界点左侧数组  
  23.     }  
  24.     int right=1;  
  25.     if(i<length-1)  
  26.     {  
  27.         right=verify_is_post(s+i,length-i-1);//分界点右侧数组  
  28.     }  
  29.     return left&&right;  
  30.   
  31. }  
  32. void main()  
  33. {  
  34.     int s1[]={5,7,6,9,11,10,8};  
  35.     int s2[]={7,4,6,5,8};  
  36.     int length1=sizeof(s1)/sizeof(int);  
  37.     int result1=verify_is_post(s1,length1);  
  38.     if(result1)  
  39.         printf("yes,it is the post-order traversal.\n");  
  40.     else  
  41.         printf("no,it is not the post-order traversal.\n");  
  42.     int length2=sizeof(s2)/sizeof(int);  
  43.     int result2=verify_is_post(s2,length2);  
  44.     if(result2)  
  45.         printf("yes,it is the post-order traversal.\n");  
  46.     else  
  47.         printf("no,it is not the post-order traversal.\n");  
  48.   
  49. }  


数据结构与算法面试题80道 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / \ 6 14 / \ / \ 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 首先我们定义的二元查找树 节点的数据结构如下: struct BSTreeNode{int m_nValue; // value of nodeBSTreeNode *m_pLeft; // left child of nodeBSTreeNo 阅读详情

相关推荐

数据结构面试题(含答案)

将数组 1,1,1,2,2,2,2,2,7,7,1,5,5,5,0 转变成 1,2,7,1,5,0 问题比较简单,要注意的是这个数。整数序列-2, 11, -4, 13, -5, 2, -5, -3, 12, -9 的最大子序列的和为 21。比如一个链表是这样的: 1->2->3->4->5 通过反转后成为 5->4->3->2->1。假设 Sum(i, j)是 A[i] ... A[j]的和,那。例如 N1->N2->N3->N4->N5->N2 就是一个有环的链表,环的开始结点是 N5 这里有一个。

Alonei6的博客 1343

最佳数据结构常见面试题和答案合集

队列是一种线性结构形式,它遵循 FIFO(先进先出)方法来访问元素。Dequeue、enqueue、front、rear 是队列的基本操作。像堆栈一样,队列可以使用数组和链表来实现。在堆栈中,最近添加的项目首先被删除。与此相反,在队列的情况下,首先删除最近最少添加的项目。

不定时分享最优质的网络技术与教程,满满的干货。 4407

C语言【23道】经典面试题【下】

必知必会的面试经典题

choice~的博客 1134

保研面试 算法题_计算机考研/保研复试重点整理-数据结构篇

先来一个知识框架图,前方高能预警好了,看完这个框架,你慌了吗?大家心里有个数之后,我们开始划重点,都去给我背!一、什么是数据结构?数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。结构包括逻辑结构和物理结构。数据的逻辑结构包括4种,(1)集合:数据元素之间除了有相同的数据类型再没有其他的关系 (2)线性结构:数据元素之间是一对一的关系 (3)树形结构...

weixin_39644915的博客 1947

用python-docx打造Python面试题55道:考点解析与随机抽题脚本

在技术面试准备中,结构化整理知识点与自动化生成复习材料是常见需求。python-docx 提供了一套操作 Word 文档的 Python 接口,通过遍历段落、设置样式,可以将题目与答案组织成规范文档。利用脚本解析文档结构,能实现题号校验、答案提取与内容统计,而 ast 与 subprocess 可对示例代码做语法和运行校验,保证题库质量。面试前,借助随机抽题脚本与薄弱清单,可将静态文档变成交互式自测工具。本文基于 Python 面试题 55 道文档,从考点分布到高频题解析(如 GIL、装饰器、可变对象与 i

weixin_34116482的博客 283

从课堂笔记到动手实践:用Multisim仿真高频谐振功放(丙类)的完整流程

本文详细介绍了使用Multisim仿真高频谐振功放(丙类)的完整流程,从仿真环境准备到电路搭建、偏置网络设计、信号注入与波形观测,再到效率优化与性能验证。通过14个关键操作步骤,帮助读者将高频电子线路的理论知识转化为动手实践,深入理解丙类功放的非线性工作状态和效率优化技巧。

weixin_30701575的博客 518

数据结构面试常见问题

本文介绍了与数据结构相关的面试题。

代码星辰的博客 1万+

【论文阅读】High-Resolution Image Synthesis with Latent Diffusion Models

为了降低训练扩散模型的算力,LDMs使用一个Autoencoder去学习能尽量表达原始image space的低维空间表达(latent embedding),大大减少需要的算力。在RGB空间:编码器encoder:,将x压缩成低维表示解码器decoder: D,将低维表示z还原成原始图像空间。1. 加入Autoencoder(上图中左侧红色部分),使得扩散过程在latent space下,提高图像生成的效率;

weixin_57974242的博客 1万+

80道常见数据结构面试题及其解法(2)

第13题: 输入一个单向链表,输出该链表中倒数第k 个结点。链表的倒数第0个结点为链表的尾指针。 两个指针,第一个先走K步,第二个再和第一个一起走,一直到第一个走到尾结点。那第二个指针的位置就是所求。 14.题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。 要求时间复杂度是O(n)。如果有多对数字的和等于输

eff_vector的博客 798

2026年数据中心运行与管理专业人才培养基地建设方案(高职、数据中心运行与管理新专业、人才培养、专业代码:510310)

摘要: 为响应国家“东数西算”战略和数字经济需求,我校拟联合行业领军企业建设数据中心运行与管理人才培养基地。项目基于国家政策引导和产业快速发展背景,针对行业10万人才缺口,对标教育部新设专业标准(510310),分三阶段实施五年规划:专业奠基(2026-2028)、内涵深化(2028-2029)、辐射引领(2030-2031)。建设内容涵盖校企协同岗位能力分析、模块化课程开发(如网络管理、自动化运维等)、实训基地搭建及“课证融通”培养模式,重点培养基础设施、网络服务、运维托管三类岗位技能人才,目标建成区域性

啊碧根果的博客 1684

MATLAB安装

Matlab 2016a 安装包及破解教程百度云分享链接: 链接:https://pan.baidu.com/s/1i6BgD8p       密码:17gg   Matlab安装教程: 1、下载文件,得到R2016a_win64.part1.rar、R2016a_win64.part2.rar两部分安装文件和Matlab 2016a Win64 Crack破解文件。 2、解压安装文件(解...

qq_36734094的博客 17万+

leetcode 最常见的 150 道前端面试题(简单题上)

本文题目选自 LeetCode 精选 TOP 面试题[1],而这些题在自己和同事亲身经历中,确实遇到的几率在百分之80%以上(成都和北京的前端岗位)。本文挑选其中所有简单题做归类和解法分析。后续更新所有中等题分析。为了帮助大家快速刷题,通过将数据结构 + 题型的方式总结出来,比如说哈希表拥有记数的功能,如果题目中包含字眼至多xx次至少xx次唯一等等字眼,可以联想到用哈希表来解决。刷个3-4道类似的题,就会养成一种条件反射。

2401_84446919的博客 1214

高通Camera IFE时钟配置

高通Camera IFE时钟配置中的minHorizontalBlanking和minVerticalBlanking配置计算方法

一个懒癌的驱动工程师的随笔分享 6167

【数据结构】 二叉树面试题讲解->贰

二叉树的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于二叉树的应用题目,马上要进行秋招了。希望对你们有帮助 _😀 编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。输入包括1行字符串,长度不超过100。可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列

m0_71731682的博客 3366

在windows中安装并启动ActiveMQ5.16.2

打开ActiveMQ官网 下载ActiveMQ 点击apache-activemq-5.16.2-bin.zip进行下载 下载发后解压到c盘根目录下 在powershell中输入 ./activemq start启动 ActiveMQ服务 htpp://127.0.0.1:8161访问ActiveMQ控制台 ...

934

Error response from daemon: Get “https://index.docker.io/v1/search?q=nginx&n=25“:

在使用docker seach 命令搜索镜像的时候遇到这个错误,docker pull是可以正常下载镜像的,关于这个问题,本文提供解决方案,完全可行。

猿小白的博客 1万+

[整理III]微软等数据结构+算法面试100题[最新第61-80题]

精选微软等数据结构+算法面试100题[第61-80题] --最新整理公布 昨日,11.19,最新整理了,第61-80题,现在公布。 可以这么说,绝大部分的面试题,都是这100道题系列的翻版, 此微软等公司数据结构+算法面试100题系列,是极具代表性的经典面试题。 我曾经暗暗问自己,不知道我是否把面试题基本上都搜集整理尽了, 而当然,对你更重要的是,我自个还提...

jinghuainfo 107

ATECC508A芯片开发笔记(三):获取508A串号、随机数源码及I2C抓包分析

ATECC508A芯片开发笔记(三):读取508A串号、获取随机数源码及I2C抓包分析 APP层函数编写及源码分析 At508_GetSernum() GetSernum抓包记录 At508_GetRandom( ) GetRandom抓包记录 经过前两章节,CryptoAuthlib库已经成功适配在代码中了,下面简单测试一下API函数,并分析下I2C通讯流程: APP层函数编写及源码分析利用li

HowieXue 薛永浩的博客 2万+

剑指offer面试题总结

http://www.aachin.info/tech/%E5%89%91%E6%8C%87offer%E9%9D%A2%E8%AF%95%E9%A2%98%E6%80%BB%E7%BB%93%EF%BC%881%EF%BC%89/ 面试题3:查找排序二维数组 面试题4:替换空格为%20 扩展1-复制排序数组B至尾部有足够空余空间的排序数组A。  (我记得我最近一次感叹逆序思

2674

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

数据结构和算法面试题java,面试 数据结构和算法_java数据结构和算法面试题_挑战数据结构和算法面试题——左旋转字符串...

题目来源“数据结构与算法面试题80道”。在此给出我的解法,如你有更好的解法,欢迎留言。问题分析:本题是常见的旋转字符串的问题,解决的方法是两步旋转的方法:方法:void do_reverse(char *p_start, char *p_end){ if (NULL == p_start || NULL == p_end || p_start > p_end) return; c...

weixin_28985877的博客 97

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

80后程序员感慨中年危机,关于SQL书写建议&索引优化的总结

内容介绍 这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现。针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮助广 大程序员的面试准备做到万无-一失。 “刷”完本书后,你就是“题王”! 本书采用题目+解答的方式组织内容,并把面试题类型相近或者解法相近的题目尽量放在- -起,读者在学习本书时很容易看出面试题解法之间的联系,使知识的学习避免碎片化。书中将所有的面试题从难到易依次分为“将、校、尉、士”四个档次,方便读者有针

m0_56662269的博客 111

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: 第一份csdn博客
下一篇: 80道常见数据结构面试题及其解法(2)
VectorC0de
博客等级 码龄14年 1粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值