zoukankan      html  css  js  c++  java
  • 力扣每日一题

    不能因为每次做一道算法题就开个随笔,故开个记录贴。坚持就是胜利!

    IT:https://blog.csdn.net/hackbuteer1/category_9261019.html

    初期我不知道该怎么讲解,所以先以代码显示为主。。。。

    2021/2/28

    单调数列:如果数组是单调递增或单调递减的,那么它是单调的。 当给定的数组 A 是单调数组时返回 true,否则返回 false

    题目地址:896. 单调数列

    代码:(自己编写)

    class Solution {
    public:
        bool isMonotonic(vector<int>& A) {
            int size = A.size();
            if(A[size-1]>A[0])
            {
                for(int i = 0; i<size-1;i++)
                {
                    if(A[i+1]<A[i])
                    {
                        return false;
                    }              
    
                }
            }
            else
            {
                for(int j = 0; j<size-1;j++)
                {
                    if(A[j+1]>A[j])
                    {
                        return false;
                    }              
    
                }
            }
            return true;
        }
    };

    2021/3/1

    给定整数1,2,4,1,7,8,3 ,求第n个之前加起来的最大值(被加的整数必须是间隔的)

    使用动态规划,

    //递归
    int opt(std::vector<int>& nums,int i)
    {
        if (i == 0)
        {
            return 1;
        }
        else if(i == 1)
        {
            return 2;
        }
        else
        {
            int A = opt(nums, i - 2) + nums[i];
            int B = opt(nums, i - 1);
            return max(A, B);
        }
         
    }
    
    //非递归
    int dp_opt(std::vector<int>& nums)
    {
        int* arr = new int[nums.size()];
        memset(arr, 0, nums.size());
        arr[0] = 1;
        arr[1] = max(arr[0], arr[1]);
        for (int i = 2; i < nums.size(); i++)
        {
            int A = arr[i - 2] + nums[i];
            int B = arr[i - 1];
            arr[i] = max(A, B);
        }
        return arr[nums.size() - 1];
    
    }
    
    opt(n, 6);
    dp_opt(n);

    拓展:给定一串数字{ 3,34,4,12,5,2 }, 给出第n个数字之前加起来的和(只要有数字相加等于S即可)是否等于S,如果可以,返回true, 否则false

    递归方法,也是动态规划

    bool subset(std::vector<int>& nums, int i, int s)
    {
        if (s == 0)
        {
            return true;
        }
        else if (i == 0)
        {
            return nums[0] == s;
        }
        else if (nums[i] > s)
        {
            return subset(nums,i-1,s);
        }
        else
        {
            int A = subset(nums, i - 1, s-nums[i]);
            int B = subset(nums, i - 1, s);
            return A || B;
        }
    }
    
    bool l = subset(nums, 5, 13);
    

    2021/3/3

    给定某范围数组[m,n],求解m到n之间所有数 '与' 之后的结果,包括m,n

    一共有两种方法,都写在代码里了

    #include <stdio.h>
    #include <stdlib.h>
    
    int smb(int m)
    {
        int result = m;
        int count = 0;
        while (result > 0)
        {
            result = (result >> 1);
            count++;
        }
        return count - 1;
    }
    
    int set_bit(int m, int i)
    {
        return (m | (1 << i));
    }
    
    int get_bit(int m, int i)
    {
        return ((m >> i) & 1);
    }
    
    int rangeresult(int m, int n)
    {
        int smb1 = smb(m);
        int smb2 = smb(n);
        if (smb1 != smb2)
        {
            return 0;
        }
        int msb = smb1;
        int result = 0;
        while (msb >= 0)
        {
            int x = get_bit(m, msb);
            int y = get_bit(n, msb);
            if (x != y)
            {
                return result;
            }
            else if (x == 1)
            {
                result = set_bit(result, msb);           
            }      
             msb--;      
        }
    
        return result;
    }
    int set_bit0(int m, int i) 
    {
        return m &= ~(0x1 << i);
    }
    int rangeresult2(int m, int n)
    {
        int smb1 = smb(m);
        int smb2 = smb(n);
        if (smb1 != smb2)
        {
            return 0;
        }
        int result = n;
        int x = 0;
        int temp = 0;
        while (result >= m)
        {
            if (result == 1)
            {
                return 1;
            }
            result = set_bit0(result, x);      
            x++;
            temp = result;
        }
        return temp;
    }
    int main()
    {
        printf("%d
    ",smb(4));
        printf("%x
    ", rangeresult(23, 27));
        printf("%x", rangeresult2(23, 27));
        return 0;
    }

    2021/3/4

    汉诺塔。。。。看完视频发现很简单: 推荐这个大佬的教程

    代码:

    #include <stdio.h>
    
    void hannuota(int n, char A, char B, char C)
    {
        if (n == 1)
        {
            printf("%c -> %c
    ", A, C);
        }
        else
        {
            hannuota(n - 1, A, C, B);
            printf("%c -> %c
    ", A, C);
            hannuota(n - 1, B, A, C);
            
        }
    }
    
    int main()
    {
        hannuota(4, 'A', 'B', 'C');
    
        return 0;
    }

    2021/3/5

    给定两个交叉链表m,n,求它们的交叉点的值

    除了暴力求解,时间复杂度m*n, 使用下面的方法,可以使复杂度降低到m+n

    B站视频链接:交叉链表练习题讲解

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct NodeList {
        int val;
        struct  NodeList* next;
    };
    
    int getlen_list(NodeList* node)
    {
        if (!node)
        {
            return 0;
        }
        int count = 0;
        while (node != NULL)
        {
            count++;
            node = node->next;
        }
        return count;
    }
    
    NodeList* relocate_node(NodeList* node,int n)
    {
        NodeList* p = node;
        for (int i = 0; i < n; i++)
        {
            p = p->next;
        }
        return p;
    }
    
    NodeList* common_list(NodeList* l1, NodeList* l2)
    {
        NodeList* long_list = l1;
        NodeList* short_list = l2;
        int len_1 = getlen_list(l1);
        int len_2 = getlen_list(l2);
        if (len_1 < len_2)
        {
            long_list = l2;
            short_list = l1;
        }
        int ret = abs(len_1 - len_2);
        NodeList* p1 = relocate_node(l1, ret);
        while (p1 != NULL)
        {
            if (p1 == short_list)
            {
                return p1;
            }
            p1 = p1->next;
            short_list = short_list->next;
        }
        return NULL;
    
    }
    int main()
    {
        NodeList n1, n2, n3, n4, n5, n6, n7;
        n1.val = 1;
        n2.val = 2;
        n3.val = 3;
        n4.val = 4;
        n5.val = 5;
        n6.val = 6;
        n7.val = 7;
    
        n1.next = &n2;
        n2.next = &n3;
        n3.next = &n4;
        n4.next = &n5;
        n5.next = &n6;
        n6.next = NULL;
        n7.next = &n4;
    
        printf("%d
    ", getlen_list(&n1));
        printf("%d
    ", getlen_list(&n7));
        NodeList *common_node = common_list(&n1, &n7);
        printf("%d
    ", common_node->val);
    
        return 0;
    
    }

    2021/3/6

    递归: 给定1,1,2,3,5,8,13....规律的数字,求出它们的和

    注意:求第n个数的值与求n个数之前(包含n)所有数的和的方法是有所不同的。

    #include <stdio.h>
    
    int num(int i)    //第i位数是多少
    {
        if (i == 1)
            return 1;
        else if (i == 2)
            return 1;
        else
            return num(i - 1) + num(i - 2);
    }
    
    int sum(int i)   //所有数的和
    {
        if (i == 1)
            return 1;
        else if (i == 2)
            return 2;
        else
            return sum(i - 1) + num(i);
    }
    
    int main()
    {
        printf("%d
    ", sum(8));
        return 0;
    }

    2021/3/7

    创建平衡二叉树,并求出树的高度和最大结点的值, p.s: 中序遍历可以将数从小到大列出来

    #include <stdio.h>
    
    typedef struct NodeList {
        int val;
        struct NodeList* left;
        struct NodeList* right;
    }Node;
    
    typedef struct Tree {
        Node* root;
    };
    
    void insert(Tree* tree, int data)
    {
        Node* node = new Node();
        node->val = data;
        node->left = NULL;
        node->right = NULL;
    
        if (tree->root == NULL)
        {
            tree->root = node;
        }
        else
        {
            Node* temp = tree->root;
            while (temp != NULL)
            {
                if (data < temp->val)
                {
                    if (temp->left == NULL)
                    {
                        temp->left = node;
                        return;
                    }
                    else
                    {
                        temp = temp->left;
                    }
                }
                else
                {
                    if (temp->right == NULL)
                    {
                        temp->right = node;
                        return;
                    }
                    else
                    {
                        temp = temp->right;
                    }
                }
            }
        }
    
    }
    
    void prelist(Node* node) //先序遍历
    {
        if (node != NULL)
        {
            printf("%d ", node->val);
            prelist(node->left);
            prelist(node->right);
        }
    }
    
    void midlist(Node* node) //中序遍历
    {
        if (node != NULL)
        {
            midlist(node->left);
            printf("%d ", node->val);
            midlist(node->right);
        }
    }
    
    void lastlist(Node* node) //后序遍历
    {
        if (node != NULL)
        {
            lastlist(node->left);
            lastlist(node->right);
            printf("%d ", node->val);
        }
    }
    
    int get_hightree(Node* node)
    {
        if (node == NULL)
        {
            return -1;
        }
        int left = get_hightree(node->left);
        int right = get_hightree(node->right);
        int max = left;
        if (right > max)
        {
            max = right;
        }
        return max + 1;
    }
    
    int get_maxvalue(Node* node)
    {
        int max;
        if (node == NULL)
        {
            return -1;
        }
        else
        {
            int m = get_maxvalue(node->left);
            int n = get_maxvalue(node->right);
            max = node->val;
            if (m > max)
            {
                max = m;
            }
            if (n > max)
            {
                max = n;
            }
        }
        return max;
    }
    
    int main()
    {
        int arr[9] = { 2,5,1,8,6,7,9,3,4 };
        Tree tree;
        tree.root = NULL;
        for (int i = 0; i < 9; i++)
        {
            insert(&tree, arr[i]);
        }
    
        midlist(tree.root); //中序遍历
        printf("
    ");
        int height = get_hightree(tree.root);
        printf("树高: %d
    ", height);
        int max_value = get_maxvalue(tree.root);
        printf("最大值: %d
    ", max_value);
        return 0;
    }

    2021/3/8

    已知一串数字,其中一个数字占所有数字的二分之一以上,比如{1,1,1,1,2,4,3}, 1是个数是最多的。

    我们的任务是写个算法来算出是哪个数字出现的频率最高。这里我们使用栈来实现。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int valuemax(int* arr,int len)
    {    
        int* stack = (int *)malloc(sizeof(int)*len);
        int top = -1;
        
        for (int i = 0; i < len; i++)
        {
            if (top == -1)
            {
                stack[++top] = arr[i];
            }
            else if (stack[top] == arr[i])
            {
                stack[++top] = arr[i];
            }
            else
            {
                top--;
            }
        }
        return stack[0];
    }
    
    int main()
    {
        int arr[] = { 2,8,3,2,1,1,1,1,1,7,1 };
        int len = sizeof(arr) / sizeof(int);
        int result = valuemax(arr, len);
        printf("%d
    ", result);
        return 0;
    }

    2021/3/9

    给出一串数字, 求出其中出现频率为1的数字。比如 [1,2,3,5,4,2,1,4,3],只有'5'出现一次

    这里用异或的方法,异或:如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

    #include <stdio.h>
    
    int singleNumer(int* nums, int numsize)
    {
        int result = nums[0];
        for (int i = 1; i < numsize; i++)
        {
            result = result ^ nums[i];
        }
        return result;
    }
    
    int main()
    {
        int nums[9] = { 1,2,3,5,4,2,1,4,3 };
        int res = singleNumer(nums, 9);
        printf("%d
    ", res);
    
        return 0;
    }

    2021/3/10

    镜像二叉树,递归写法

    void mirror_tree(Node* tree)
    {
        Node* node = tree;
        if ((node == NULL) || ((node->left == NULL) && (node->right == NULL)))
        {
            return;
        }
        Node* temp = node->left;
        node->left = node->right;
        node->right = temp;
    
        if (node->left)
        {
            mirror_tree(node->left);
        }
        if (node->right)
        {
            mirror_tree(node->right);
        }
    }

    非递归写法参考:二叉树的镜像(递归&非递归)

    2021/3/11

    给出两个数组,将它们按从小到大重新排序,并且将新数组放到第一个数组里,假设第一个数组空间足够大。

    比如:{ 9,10,11,12,13 }; { 1,2,3,4 };  重新排序后:{ 1,2,3,4,9,10,11,12,13 }  这里我们使用归并排序

    #include <stdio.h>
    #include <stdlib.h>
    
    int* guibing(int* arr1, int* arr2,int m,int n)
    {
        int* arr = (int*)malloc(sizeof(int) * (m + n));
        int i = 0;
        int j = 0;
        int k = 0;
    
        while (i < m && j < n)
        {
            if (arr1[i] > arr2[j])
            {
                arr[k] = arr2[j];
                j++;
            }
            else
            {
                arr[k] = arr1[i];
                i++;
            }
            k++;
        }
        while (i < m)
        {
            arr[k] = arr1[i];
            i++;
            k++;
        }
        while (j < n)
        {
            arr[k] = arr2[j];
            j++;
            k++;
        }
        arr1 = arr;
    
        return arr1;
    }
    
    int main()
    {
        int arr1[100] = { 9,10,11,12,13 };
        int arr2[4] = { 1,2,3,4 };
    
        int* arr = guibing(arr1, arr2, 5, 4);
    
        for (int i = 0; i < 9; i++)
        {
            printf("%d ", arr[i]);
        }
        return 0;
    }

    2021/3/

     开始投入QT的怀抱,回见

  • 相关阅读:
    camunda用户的一些简单操作
    assets和static
    mongoDB的常用语法
    服务发现和注册和Eureka
    camunda
    Web API系列(三) 异常处理
    Web API系列(二) Filter的使用以及执行顺序
    Web API系列(一):WEB API的适用场景、第一个实例
    WebAPI前置知识:HTTP与RestfulAPI
    【requirejs】JS模块化工具requirejs教程
  • 原文地址:https://www.cnblogs.com/strive-sun/p/14460731.html
Copyright © 2011-2022 走看看