五道考核题的复习与总结

主要思想:

对其进行桶排序

桶排序大概意思如下图:

在这里插入图片描述

如果对应的是0,也就是桶里没这个旗子,因为题目要求 是从0到n 其对应的也就是循环的次数,所以直接printf这个对应的循环次数i就行了

需要注意最后比较进行循环时候,for的条件应该取等,因为如果输入n为2,数组为 0 1 结果应该是2,需要取等才能实现。

代码实现:

#include<stdio.h>
main(){
    
    
 int n, a[99];
 int b[99]={
    
    0};
 int i;
 scanf("%d",&n);
 for(i = 0; i < n; i++){
    
    
  scanf("%d",&a[i]);
 }
 for(i = 0; i < n; i++){
    
    
  b[a[i]]++;
 }
 for(i = 0; i <= n; i++){
    
    
  if(b[i] == 0)
  printf("%d",i);
 }
}

2.
数组的头与尾,如果等于0,那么头指针向后移动一个,并且把头指针所位于的数该数进行交换,同样如果等于2,也是同理,指针向前移动一个,尾指针所位于的数与该数进行交换,但是需要注意的是如果是1
2 0这个数据,按上面的想法,

第一遍:

1 2 0(第一个数为1,不动)

第二遍(第二个数为2,与最后一个进行交换)

1 0 2

第三遍(第三个数已经交换过,变为2,他就是最后一个所以不变):

1 0 2;

并不符合题意,所以需要通过i - -在每次交换后再判断一下交换后的该值,

以1 2 0为例,

第一遍 1 2 0;

第二遍 1 0 2;

第三遍(在判断一次第二个数 )

0 1 2;

第四遍:

0 1 2

第五遍(再判断一次)

0 1 2;

代码实现:

void sortColors(int* nums, int numsSize){
    
    
    int q = 0, h, i, n, temp;
    n = numsSize;
    h = n - 1;
    for (i = 0; i < n; i++) {
    
    
        if (h < i) {
    
    
            break;
        }
        if (nums[i] == 0) {
    
    
            if (i != q) {
    
    
                temp = nums[q];
                nums[q] = nums[i];
                nums[i] = temp;
                q++;
                i--;
                continue;
            }
        }
        if (nums[i] == 2) {
    
    
            if (i != h) {
    
    
                temp = nums[h];
                nums[h] = nums[i];
                nums[i] = temp;
                h--;
                i--;
                continue;
            }
        }
    }
}

3.
主要思想:

Strstr函数的应用
strstr函数的介绍

先用一个数组a1把a数组保存起来(方便后面的strcat),用指针指向strstr函数的结果,进行循环,循环条件是p == NULL,每次连接a1与a,这样a1是不断链接的结果而a不改变,再通过strstr函数来进行比较
如果p不是空,那么就说明子串已经出现,循环结束。循环次数就是答案。输出 -1的情况就是都没找到
我的想法是每次记录新增加的个数,如果新增加的个数比b的长度都要多并且此时p还是Null那么把flag变为-1即可。

源代码:

#include<stdio.h>
#include<string.h>
main(){
    
    
 char a[99], b[99], a1[30001]={
    
    0};
 int i ,j, flag = 1, n , m, sum = 0;
 gets(a);
 gets(b);
 n = strlen(a);
 m = strlen(b);
 for(i = 0; i < n; i++){
    
    
  a1[i] = a[i];
 }
 char *p = NULL;
    p = strstr(a,b);
 while(p == NULL){
    
    
  strcat(a1,a);
  p = strstr(a1,b);
  flag++;
  sum += n;
  if(sum > m && p  == NULL)
  {
    
    
   flag = -1;
   break;
  } 
 }
 printf("%d",flag);
}

在提交测试时发现时间效率不高 会在数值很多时 超时,比如
“a”
“aaaaaaaaaaaa………((一直到最大限度)”
参考了leetcode上的一个解法 中间的解法都是一样的,但是在判断何时结束时我是累加起来进行比较,后判断是否结束。而这个解法是通过先定下来边界,边界为m + n后向上取n的整数倍,后通过for循环来判断是否到边界,如果已经到边界则不考虑其他的就直接return -1即可,中间如果i * aLen >= bLen 且strstr(temp, B) != NULL,则return i。

源代码:


int repeatedStringMatch(char * A, char * B){
    
    

    int aLen = strlen(A);

    int bLen = strlen(B);

    // 超过一定倍数不可能再是子串:fac边界为 aLen + bLen向上取aLen整数倍

    int fac;

    // aLen = 9999, bLen = 10000时,需要的fac有3倍

    char temp[30001] = {
    
    0};

 

    if(bLen % aLen == 0){
    
    

        fac = bLen / aLen + 1;

    }

    else{
    
    

        fac = (bLen / aLen + 1) + 1;

    }

 

    int i;

    for(i = 1; i <= fac; i++){
    
    

        // 用strcat实现字符串叠加

        strcat(temp, A);

        // temp长度等于或超过B时strstr比较子串

        if(i * aLen >= bLen){
    
    

            if(strstr(temp, B) != NULL){
    
    

                return i;

            }

        }

    }

    return -1;

}

**4.**反转链表

有点类似头插法,先把head->next的这个节点保存到p1中,再令head->next变为NULL,这样最后一个节点就完成了,然后通过循环,每次都用新的指针保存p1->next的值,使p1连接上head,同时head也不断向前移动,p1每次都等于保存过的那个指针,也就是向原链表后面移动。

1 2 3 4 5为例

Head p1 p2

第一步

Head->next = NULL

1 NULL;

进入循环

一、2 1 NULL

二、head = 2(head向前移),p1 = 3;

不断循环 直到p1为null;

源代码:

#include<stdio.h>

#include<stdlib.h>

struct ListNode {

int val;

struct ListNode *next;

};

struct ListNode *head;

struct ListNode * creat(){

struct ListNode *p, *head, *end;

head = end = NULL;

p = (struct ListNode
*)malloc(sizeof(struct ListNode));

scanf("%d",&p->val);

while(p->val != -1){

if(head == NULL){

head = p;

}

else

end->next = p;

end = p;

p = (struct ListNode *)malloc(sizeof(struct ListNode));

scanf("%d",&p->val);

}

end->next = NULL;

return head;

}

struct ListNode *fanzhuan(struct ListNode *head){

struct ListNode *p1, *p2;

p1 = p2 =NULL;

if(head == NULL){

return NULL;

}

p1 = head->next;

head->next = NULL;

while(p1){

p2 = p1->next;

p1->next = head;

head = p1;

p1 = p2;

}

return head;

}

main(){

struct ListNode *p, *head;

head = creat();

p = fanzhuan(head);

for(; p != NULL; p = p->next){

printf("%d",p->val);

}
}

5. 用4的反转链表,先反转,然后与正常的进行比较即可。

#include<stdio.h>

#include<stdlib.h>

struct ListNode {

int val;

struct ListNode *next;

};

struct ListNode *head;

struct ListNode * creat(){

struct ListNode *p, *head, *end;

head = end = NULL;

p = (struct ListNode
*)malloc(sizeof(struct ListNode));

scanf("%d",&p->val);

while(p->val != -1){

if(head == NULL){

head = p;

}

else

end->next = p;

end = p;

p = (struct ListNode *)malloc(sizeof(struct
ListNode));

scanf("%d",&p->val);

}

end->next = NULL;

return head;

}

panduan(struct ListNode *head){

struct ListNode *p1, *p2, *p3, *p4, *p5 = NULL;

int n = 0;

while(p5 != NULL){

p5 = p5->next;

n++;

}

p3 = head;

p4 = head;

p1 = p2 = NULL;

p1 = p3->next;

p3->next = NULL;

while(p1){

p2 = p1->next;

p1->next = p3;

p3 = p1;

p1 = p2;

}

for(int i = 0; i <= n/2;i++){

if(p4->val != p3->val){

printf(“false”);

return 0;
}if(i == n/2){

printf(“true”);

return 0;

}

}

}

main(){

struct ListNode *p, *head;

head = creat();

panduan(head);

}

猜你喜欢

转载自blog.csdn.net/m0_46110288/article/details/106309311