打卡leetcode第10天

本文详细介绍了两种常见的算法技巧——哈希表和单调栈,并提供了具体的代码实现。首先,通过哈希表法解决寻找数组中每个元素的下一个更大元素问题,时间复杂度为O(m+n)。接着,利用单调栈解决132模式的查找,确保在O(n)的时间内完成。最后,展示了如何用递归和动态规划计算杨辉三角的某一行,以及快速判断一个数是否为完全平方数的方法。这些算法在解决数组和数列问题上非常实用。
摘要由CSDN通过智能技术生成

1.下一个更大的元素

【分析】

法1,暴力输出法

时间复杂度:O(mn),空间O(1)

【代码】C

int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
     int *ans=(int *)malloc(sizeof(int)*nums1Size);
     for(int i=0;i<nums1Size;i++){
         int j=0;
         while(j<nums2Size && nums1[i]!=nums2[j]){
             j++;
         }
         int k=j+1;
         while(k<nums2Size&&nums2[k]<nums2[j]){
             k++;
         }
         ans[i]=k<nums2Size?nums2[k]:-1;
           
    }
    *returnSize = nums1Size;
    return ans;
}

法2:哈希表法

时间复杂度:O(m+n),空间O(n)

【代码】C++

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int,int> hashmap;
        stack<int> st;
        for (int i = nums2.size() - 1; i >= 0; --i) {
            int num = nums2[i];
            while (!st.empty() && num >= st.top()) {
                st.pop();
            }
            hashmap[num] = st.empty() ? -1 : st.top();
            st.push(num);
        }
        vector<int> res(nums1.size());
        for (int i = 0; i < nums1.size(); ++i) {
            res[i] = hashmap[nums1[i]];
        }
        return res;
    }
};

2.132模式

【题目】

 【分析】

法1:暴力法:

bool find132pattern(int* nums, int numsSize){
    if (numsSize < 3) {
        return false;
    }
    int min[numsSize];
    int i, j;
    
    /* 维护[0,j-1]区间的最小值, 即题目要求的1 */
    min[0] = nums[0];
    for (i = 1; i < numsSize; i++) {
        min[i] = fmin(nums[i], min[i - 1]);
    }
    
    /* 对于每个a[j]>a[i], 在区间[j+1,n-1]找到3, 1 < 3 < 2 */
    for (i = 1; i < numsSize - 1; i++) {
        if (nums[i] > min[i]) {
            for (j = i + 1; j < numsSize; j++) {
                if (nums[i] > nums[j] && nums[j] > min[i]) {
                    return true;
                }
            }
        }
    }
    return false;
}

法2:单调栈法:

【C】

bool find132pattern(int* nums, int numsSize){
    if (numsSize < 3) {
        return false;
    }
    int min[numsSize];
    int stack[numsSize];
    int top = 0;
    int i, j, num;
    
    /* 维护[0,j-1]区间的最小值, 即题目要求的1 */
    min[0] = nums[0];
    for (i = 1; i < numsSize; i++) {
        min[i] = fmin(nums[i], min[i - 1]);
    }
    
    /* 使用单调栈去找3, 单调递减栈, 小数出栈 */
    for (j = numsSize - 1; j >= 1; j--) {
        num = INT_MIN;
        while (top > 0 && nums[j] > stack[top - 1]) {
            num = stack[--top];  /* 出栈元素3为小于a[j]的最大值 */
        }
        if (num > min[j]) {      /* 如果3大于1, 则返回true */
            return true;
        }
        stack[top++] = nums[j];
    }
    return false;
}

【C++】

class Solution {
public:
    bool find132pattern(vector<int>& nums) {
        stack<int> st;
        int n = nums.size(), k = INT_MIN;
        for(int i = n - 1; i >= 0; i--){
            if(nums[i] < k) return true;
            while(!st.empty() and st.top() < nums[i]) { 
                k = max(k,st.top()); st.pop();
            }
            st.push(nums[i]);
        }
        return false;
    }
};

3.杨辉三角

 

【分析】

法1:递归

--递推--
int* getRow(int rowIndex, int* returnSize){
    *returnSize=rowIndex+1;
    int* C[rowIndex+1];
    for(int i=0;i<=rowIndex;i++){
        C[i]=malloc(sizeof(int)*(i+1));
        C[i][0]=C[i][i]=1;
        for(int j=1;j<i;j++){
            C[i][j]=C[i-1][j-1]+C[i-1][j];
        }
    }
    return C[rowIndex];
}
--优化--
int* getRow(int rowIndex, int* returnSize) {
    *returnSize = rowIndex + 1;
    int* row = malloc(sizeof(int) * (*returnSize));
    memset(row, 0, sizeof(int) * (*returnSize));
    row[0] = 1;
    for (int i = 1; i <= rowIndex; ++i) {
        for (int j = i; j > 0; --j) {
            row[j] += row[j - 1];
        }
    }
    return row;
}

法二:公式:

 

1LL是long long int 长长整形

int* getRow(int rowIndex, int* returnSize) {
    *returnSize = rowIndex + 1;
    int* row = malloc(sizeof(int) * (*returnSize));
    row[0] = 1;
    for (int i = 1; i <= rowIndex; ++i) {
        row[i] = 1LL * row[i - 1] * (rowIndex - i + 1) / i;
    }
    return row;
}

 4.完全平方数

【分析】

法1:动态规划

时间复杂度:O(n)
空间复杂度:O(1)

int numSquares(int n) 
{
    int dp[n +1];   //定义dp的大小
    dp[0] = 0;      //定义dp的初始状态
    int min; 
    int i,j;

    //转移方程为:
    /*
    min  = fmin(min,i - [z^2]);
    dp[i]= min + 1;
    */
    for(i = 1 ; i <= n ; i++)
    {
        min = INT_MAX;
        for( j = 1 ; j*j <= i;j++)
        {
            min = fmin(min, dp[i - j * j]);
        }
        dp[i] = min + 1;
    }
    return dp[n];
}

法2:公式分析

bool isPerfectSquare(int x) {
    int y = sqrt(x);
    return y * y == x;
}

// 判断是否能表示为 4^k*(8m+7)
bool checkAnswer4(int x) {
    while (x % 4 == 0) {
        x /= 4;
    }
    return x % 8 == 7;
}

int numSquares(int n) {
    if (isPerfectSquare(n)) {
        return 1;
    }
    if (checkAnswer4(n)) {
        return 4;
    }
    for (int i = 1; i * i <= n; i++) {
        int j = n - i * i;
        if (isPerfectSquare(j)) {
            return 2;
        }
    }
    return 3;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值