初级算法整理

提示:这篇文章主要是总结一些初级算法。意识到无数的刷题可能会增加算法能力,但是会需要很长的时间,这个初始算法就像是公式,在算法题中能够套用。虽然不知道是否可以达到这种效果,但是有一点,如果连初级算法都不会,那么算法题会很难做吧。


前言

可以一点点的整理,增加。


提示:以下是本篇文章正文内容,下面案例可供参考

一、二分查找法

这个是个很基础的算法了,之前做了会做,现在再做一次(2023年6月1日14:31:59)发现还是做错了,把错题一并整理在这。

1、数组查找

void binaryAlgorithmWrong()
{
    int targetNum = 0;
    while(scanf("%d",&targetNum) != NULL)
    {
        int array[10] = {63,2,6,24,19,34,22,9,45,11};
        qsort(array, 10, sizeof(int), compare);
        int slow = 0;
        int fast = 10;
        while(slow + 1 < fast)
        {
            int index = (fast + slow) / 2;
            if(array[index] < targetNum)
            {
                slow = index;
            }
            else if(array[index] > targetNum)
            {
                fast = index;
            }
            else if(array[index] == targetNum)
            {
                printf("%d\n",index);
                return;
            }
        }

        printf("not exist\n");
        return;
    }

    return;
}

int main()
{
    binaryAlgorithm();
    cout << "Hello world!" << endl;
    return 0;
}

正确示例:

//输入目标数,如果该数在数组中,返回下标,如果不在,返回not exist
void binaryAlgorithm()
{
    int targetNum = 0;
    while(scanf("%d",&targetNum) != NULL)
    {
        int array[10] = {63,2,6,24,19,34,22,9,45,11};
        qsort(array, 10, sizeof(int), compare);
        int slow = 0;
        int fast = 9;
        while(slow <= fast)
        {
            int index = (fast + slow) / 2;
            if(array[index] < targetNum)
            {
                slow = index + 1;
            }
            else if(array[index] > targetNum)
            {
                fast = index - 1;
            }
            else if(array[index] == targetNum)
            {
                printf("%d\n",index);
                return;
            }
        }

        printf("not exist\n");
        return;
    }

    return;

}

int main()
{
    binaryAlgorithm();
    cout << "Hello world!" << endl;
    return 0;
}

为什么第一种方法是无法得到正确的结果,想了一下,应该是不进行+1时,有的元素不能被访问到。比如如果targetNum是array[0],则最后都得不到正确的结果。+1时保证了元素每次都是更新的,被剔掉的元素正是此次判断不等于targerNum的元素,所以不会引入bug。

二、交换数值

1.反转字符串

反面示例:

//正确代码
void reverseString(char* s, int sSize){
    int slow = 0;
    for(int i = slow; i < sSize / 2; i++)
    {
        char temp = s[i];
        s[i] = s[sSize - i - 1];
        s[sSize - i - 1] = temp;
    }
}

//反面代码
void reverseString(char* s, int sSize){
    int slow = 0;
    for(int i = slow; i < sSize / 2; i++)
    {
        char temp = s[slow ];
        s[i] = s[sSize - slow - 1];
        s[sSize - slow - 1] = temp;
    }
}

//竟然还会范这个错误,一直调试都没发现问题,还在怀疑是不是因为数组穿指针没有改变数据。。。
//很低级的错误,记录一下

2.翻转整数

先看题目:

整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。
 

示例 1:

输入:x = 123
输出:321
示例 2:

输入:x = -123
输出:-321
示例 3:

输入:x = 120
输出:21
示例 4:

输入:x = 0
输出:0
 

提示:

-231 <= x <= 231 - 1

代码如下

// int reverse(int x){
//     int xcopy = x;
//     int count = 0;
//     while(xcopy)
//     {
//         xcopy /= 10;
//         count++;
//     }

//     char *charx = (char*)malloc(count+1);
//    // memset(charx, '\0', count+1);
//     if(charx == NULL)
//     {
//         return 0;
//     }
    
//     sprintf(charx, "%d", x);

//     int len = strlen(charx);
//     int slow = 0;
//     for(int i = 0; i < len / 2; i++)
//     {
//         char temp = charx[i];
//         charx[i] = charx[len - i - 1];
//         charx[len - i - 1] = temp;
//     }
//     int num = atoi(charx);

//     if(num > pow(2,31) - 1 || num < -pow(2,31))
//     {
//         return 0;
//     }
    
//     return num;
// }

int reverse(int x){
    long num = 0;
    while(x)
    {
        int i = x % 10;
        
        x = x / 10;
        num = num * 10 + i;
    }

    if(num != (int)num)
    {
        return 0;
    } 
    
    return num;
}

高下立判!!

3、验证回文串

这个题目一共花了两次时间做好。第一次做的代码即代码块中的注释代码,做好代码提交代码的时候报了好几次未过。先后是"a."、",."、"0P"。一直根据未过信息修改代码,前前后后改了好几次,最后在"0P"时彻底卡死了,代码改的也烦了,就放弃了。觉得自己没有整理好逻辑和算法。第二次做的时候,就彻底理清了思路,想好算法逻辑,简单修改一次就Ace了。代码如下:

// bool isPalindrome(char * s){
//     int len = strlen(s);
//     int head = 0;
//     int rear = len - 1;
//     while(head < rear)
//     {
//         if( isalpha(s[head]) )
//         {
//            if(s[head] - s[rear] != 0 && abs(s[head] - s[rear]) != 32)
//            {
//                return false;
//            }
//            head++;
//            rear--;
//         }
//         if( isdigit(s[head]) )
//         {
//            if( s[head] != s[rear] )
//            {
//                return false;
//            }
//            head++;
//            rear--;
//         }
//         if(!isalpha(s[head]))
//         {
//             while(!isalpha(s[head]))
//             {
//                 head++;
//                 if(head > len)
//                 {
//                     break;
//                 }
//             }
//         }
//         if(!isalpha(s[rear]))
//         {
//             while(!isalpha(s[rear]))
//             {
//                 rear--;
//                 if(rear < 0)
//                 {
//                     break;
//                 }
//             }
//         }
//     }

//     return true;
// }

bool IsAlphaOrDigital(char cha)
{
    if(isalpha(cha) || isdigit(cha))
    {
        return true;
    }

    return false;
}

bool isPalindrome(char * s){
    int len = strlen(s);
    int head = 0;
    int rear = len - 1;
    while(head < rear)
    {
        if(IsAlphaOrDigital(s[head]) && IsAlphaOrDigital(s[rear]))
        {
            if(isalpha(s[head]))
            {
                if( s[head] == s[rear] || abs(s[head] - s[rear]) == 32 )
                {
                    head++;
                    rear--;
                    continue;
                }
                return false;
            }
            else if(isdigit(s[head]))
            {
                if( s[head] == s[rear] )
                {
                    head++;
                    rear--;
                    continue;
                }
                return false;
            }
        }
        if( !IsAlphaOrDigital(s[head]) )
        {
            while(!IsAlphaOrDigital(s[head]) && head < len)
            {
                head++;
            }
        }
        if( !IsAlphaOrDigital(s[rear]))
        {
            while(!IsAlphaOrDigital(s[rear])  && rear > 0)
            {
                rear--;
            }
        }
    }

    return true;
}

 4、实现atoi

void findCharacterIndex(char* s, int* i)
{
    while(s[*i] == ' ')
    {
        (*i)++;
    }
}

bool isSubCharacter(char* s, int* i)
{
    if(s[*i] == '+')
    {
        (*i)++;
        return false;
    }
    else if(s[*i] == '-')
    {
        (*i)++;
        return true;
    }
    
    return false;
}

int myAtoi(char * s){
    int len = strlen(s);
    int index = 0; 
    findCharacterIndex(s, &index);
    bool isSub = isSubCharacter(s, &index);
    long num = 0;
    while(isdigit(s[index]))
    {
        if(num > LONG_MAX / 10 - 9)
        {
            break;
        }
        num = num * 10 + s[index] - '0';
        
        index++;
    }

    if(num != (int)num)
    {
        num = isSub ? INT_MAX + 1 : INT_MAX;
    }

    return isSub ? (0 - num) : num;
}

这个题目是做的第一次就Ace的。这个题目中有两个坑,一个就是*i++,这样写是错的,要改成(*i)++;

第二个就是

if(num > LONG_MAX / 10 - 9)
{
       break;
}

不然会long型数组溢出,leetcode会检查出来,其他编译器可就不会提示了。

这边昨天想了一下,可以优化一下代码性能,改成

if(num > INT_MAX)
{
       break;
}

 根据提交结果,效率确实提升了很多!

5、实现strstr()

int strStr(char * haystack, char * needle){
    int len1 = strlen(haystack);
    int len2 = strlen(needle);
    for(int i = 0; i < len1; i++)
    {
        int index = 0;
        int j = i;
        while(haystack[j] == needle[index] && j < len1)
        {
            j++;
            index++;
        }
        if(index == len2)
        {
            return i;
        }
    }

    return -1;
}

 提交结果

这个题目一次Ace, 而且执行时间竟然是0秒,太牛了,怎么会这么牛逼?!

三、链表

1、删除链表的倒数第几个节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    int count = 0;
    struct ListNode *node = head;
    while(node)
    {
        count++;
        node = node->next;
    }

    if(count == 1)
    {
        return head->next;
    }

    if(n == 1)
    {
        struct ListNode *temp0 = head;
        while(temp0)
        {
            if(temp0->next->next == NULL)
            {
                // temp0->val = temp0->next->val;
                temp0->next = NULL;
            }
            temp0 = temp0->next;
        }
        return head;
    }
    
    int index = count - n;
    if(index == 0)
    {
        head = head->next;
        return head;
    }
    struct ListNode *temp = head;
    int counter = 0;
    while(temp)
    {
        counter++;
        
        if(index == counter)
        {
            // int data = temp->next->next->val;
            temp->next = temp->next->next;
            // temp->next->val = data;
            break;
        }
        temp = temp->next;
    }

    return head;
}

这就是屎山代码吧。。。

2、自己写的链表

2023年6月8日14:33:48

这次写的链表只含有创建链表和打印链表

#include <iostream>

#include <stdio.h>
#include <stdlib.h>

using namespace std;

struct LianBiao
{
    int data;
    struct LianBiao *next;
};

struct LianBiao creatList(struct LianBiao* head, int len)
{
    struct LianBiao* temp = head;
    for(int i = 0; i < len; i++)
    {
        struct LianBiao* node = (struct LianBiao*)malloc(sizeof(struct LianBiao) * 1);
        node->data = i * 2;
        node->next = NULL;
        temp->next = node;
        temp = temp->next;
    }

    //free();
};

struct LianBiao creatList2(struct LianBiao* head, int len)
{
    struct LianBiao* temp = head;
    for(int i = 0; i < len; i++)
    {
        struct LianBiao* node = (struct LianBiao*)malloc(sizeof(struct LianBiao) * 1);
        node->data = i * 2;
        node->next = NULL;
        temp->next = node;
    }

    //free();
};


struct LianBiao* creatList3(int len)
{
    struct LianBiao* head = NULL;
    struct LianBiao* temp = NULL;
    for(int i = 0; i < len; i++)
    {
        struct LianBiao* node = (struct LianBiao*)malloc(sizeof(struct LianBiao) * 1);
        node->data = i * 2;
        node->next = NULL;
        if(i == 0)
        {
            head = node;
            temp = node;
        }
        else
        {
            temp->next = node;
            temp = temp->next;
        }
    }

    return head;
};

void printLianBiao(struct LianBiao* head)
{
    while(head)
    {
        int data = head->data;
        printf("%d ",data);
        head = head->next;
    }
}

int mainF()
{
    struct LianBiao* head = (struct LianBiao*)malloc(sizeof(struct LianBiao) * 1);
    creatList(head, 5);
    printLianBiao(head);

    cout << "Hello world!" << endl;
    return 0;
}


int main()
{
    struct LianBiao* head = creatList3(5);
    printLianBiao(head);

    cout << "Hello world!" << endl;
    return 0;
}

//0 2 4 6 8 Hello world!

关于链表,别人的博客详细说明:数据结构之——链表_链表数据结构_叶花永不相见的博客-CSDN博客

四、其他

3.颠倒二进制位

uint32_t reverseBits(uint32_t n) {
    char array[33] = {'\0'};
    int index = 31;
    for(int i = 0; i < 32; i++)
    {
        if(n & 0x01)
        {
            array[index--] = '1';
        }
        else
        {
            array[index--] = '0';
        }

        n = n >> 1;
    }

//    int dat = atoi(array);      //只能转十进制

    unsigned int dat = 0;

    for(int i = 31; i >= 0; i--)
    {
        if(array[i] == '1')
        {
            dat += (unsigned int)(pow(2, i) + 0.5);
        }
    }

    return dat;
}

一开始想用atoi实现的,发现不行,自己就写了下半段实现方法。其中还出了其实应该是等于'1',但是是等于1的bug。

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值