六道数据结构算法题详解

目录

1.力扣350题. 两个数组的交集 II

2.力扣121题. 买卖股票的最佳时机

3.力扣566题. 重塑矩阵

4.力扣118题. 杨辉三角

5.牛客BM13 判断一个链表是否为回文结构

6.牛客BM14 链表的奇偶重排


1.力扣350题. 两个数组的交集 II

题目:给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]

解:先将两个数组进行排序,在创建双指针,分别指向数组的第一个元素在比较大小,谁小谁先入新栈。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int cmp(const void *a_h,const void *b_h)
{
    int a=*(int*)a_h,b=*(int*)b_h;
    return a-b;
}

int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int p1=0,p2=0;//双指针
    qsort(nums1,nums1Size,sizeof(int),cmp);
    qsort(nums2,nums2Size,sizeof(int),cmp);
    *returnSize=0;
    int *ListNode=malloc(sizeof(int)*fmin(nums1Size,nums2Size));
    while(p1nums2[p2])nums2[p2++];
        else {
            ListNode[(*returnSize)++]=nums1[p1];
            p1++;
            p2++;
        }
    }
    return ListNode;
}

2.力扣121题. 买卖股票的最佳时机

题目:给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

解:我们记录今天之前的最小值[1],再记录当天之后相减进行比较,选出最大值。

int maxProfit(int* prices, int pricesSize){
    if(pricesSize<=1)return 0;
    int max=0,min=prices[0];
    for(int i=1;i

3.力扣566题. 重塑矩阵

题目:在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。

给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。

如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

示例 1:
输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** matrixReshape(int** nums, int numsSize, int* numsColSize, int r, int c, int* returnSize, int** returnColumnSizes) {
    int m = numsSize;
    int n = numsColSize[0];
    if (m * n != r * c) {
        *returnSize = numsSize;
        *returnColumnSizes = numsColSize;
        return nums;
    }
    *returnSize = r;
    *returnColumnSizes = malloc(sizeof(int) * r);
    int** ans = malloc(sizeof(int*) * r);

    for (int i = 0; i < r; i++) {
        (*returnColumnSizes)[i] = c;
        ans[i] = malloc(sizeof(int) * c);
    }
    for (int x = 0; x < m * n; ++x) {
        ans[x / c][x % c] = nums[x / n][x % n];
    }
    return ans;
}

4.力扣118题. 杨辉三角

题目:给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。

六道数据结构算法题详解_第1张图片

示例 1:

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
 

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** generate(int numRows, int* returnSize, int** returnColumnSizes) {
    int** ret = malloc(sizeof(int*) * numRows);
    *returnSize = numRows;
    *returnColumnSizes = malloc(sizeof(int) * numRows);
    for (int i = 0; i < numRows; ++i) {
        ret[i] = malloc(sizeof(int) * (i + 1));
        (*returnColumnSizes)[i] = i + 1;
        ret[i][0] = ret[i][i] = 1;
        for (int j = 1; j < i; ++j) {
            ret[i][j] = ret[i - 1][j] + ret[i - 1][j - 1];
        }
    }
    return ret;
}

5.牛客BM13 判断一个链表是否为回文结构

题目:给定一个链表,请判断该链表是否为回文结构。回文是指该字符串正序逆序完全一致。

数据范围: 链表节点数 0 \le n \le 10^50≤n≤105,链表中每个节点的值满足 |val| \le 10^7∣val∣≤107

解:我们将链表从中间分开,再对后面的链表进行反转,判断是否相等,相等则为回文结构。

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

/**
 * 
 * @param head ListNode类 the head
 * @return bool布尔型
 */
bool isPail(struct ListNode* head ) {
    // write code here
    struct ListNode *fast=head,*slow=head;
    while(fast->next!=NULL&&fast->next->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    slow=slow->next;
    struct ListNode*headtail=slow,*newhead=NULL;
    struct ListNode*tmp;
    while(headtail!=NULL)
    {
        tmp=headtail->next;
        headtail->next=newhead;
        newhead=headtail;
        headtail=tmp;
    }
    struct ListNode* headfore=head;
    while(newhead!=NULL)
    {
        if(headfore->val!=newhead->val)
        {
            return false;
        }
        headfore=headfore->next;
        newhead=newhead->next;
    }
    return true;
}

6.牛客BM14 链表的奇偶重排

题目:给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。注意是节点的编号而非节点的数值。

数据范围:节点数量满足 0 \le n \le 10^50≤n≤105,节点中的值都满足 0 \le val \le 10000≤val≤1000

要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

示例1

输入:{1,2,3,4,5,6}

复制返回值:{1,3,5,2,4,6}

复制说明:1->2->3->4->5->6->NULL

重排后为1->3->5->2->4->6->NULL

解:我们可以用双指针截断奇数位和偶数位,然后再将偶数位指向奇数位next端就可以了。 

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @return ListNode类
 */
struct ListNode* oddEvenList(struct ListNode* head ) {
    // write code here
    if(!head)
        return NULL;
    struct ListNode odd_h,even_h;
    odd_h.next=even_h.next=NULL;
    struct ListNode *odd=&odd_h,*even=&even_h;
    bool is_odd=true;
    while(head)
    {
        if(is_odd)
        {
            odd->next=head;
            odd=odd->next;
        }
        else
        {
            even->next=head;
            even=even->next;
        }
        head=head->next;
        is_odd=!is_odd;
    }
    odd->next=even_h.next;
    even->next=NULL;
    return odd_h.next;
}

你可能感兴趣的:(数据结构,数据结构)