C语言初级——练习(一)

C语言初级——练习(一)

1、合并两个有序数组

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3

输出: [1,2,2,3,5,6]

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    //冒泡排序,乱序也可用!!!
    for(int i=0;i<n;i++){//合并两个数组
        nums1[m+i]=nums2[i];
    }
    for(int i=m+n-1;i>0;i--){  //冒泡排序
        for(int j=0;j<i;j++){
            if(nums1[j]>nums1[j+1]){    
            int tmp=nums1[j];
            nums1[j]=nums1[j+1];
            nums1[j+1]=tmp;
            }
        }
    }   
}

或这采用qsort()函数的快速排序

int cmp(const void *a, const void *b)
{
    return *((int*)a) > *((int *)b);
}
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    //qsort()快速排序,乱序也可用!!!
    for(int i=0;i<n;i++){//合并两个数组
        nums1[m+i]=nums2[i];
    }
    qsort(nums1, m+n, sizeof(int), cmp);
}
2、买卖股票的最佳时机

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。

示例 1:

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

示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

int maxProfit(int* prices, int pricesSize){
    int profit=0;
    //对每个利润进行对比,保留输出最大的利润
    for(int i=0;i<pricesSize;i++){
        for(int j=i+1;j<pricesSize;j++){
            if(prices[j]-prices[i]>profit){
                profit=prices[j]-prices[i];
            }
        }
    }
    return profit;
}
3、只出现一次的数字

做法:(暴力枚举/记录法/排序法/索引法/二进制异或操作)

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:
输入: [2,2,1]
输出: 1

示例 2:
输入: [4,1,2,1,2]
输出: 4

//二进制异或 a^a=0   0^a=a  且满足结合律和交换律
int singleNumber(int* nums, int numsSize){
	int xor=0;
	for(int i=0;i<numsSize;i++){
        xor^=nums[i];
	}
	return xor;
}
//暴力枚举   缺点:时间复杂度高
int singleNumber(int* nums, int numsSize){
	if( numsSize <= 1 ){
		return nums[0];
	}
    int num=0;
	for( int i = 0; i < numsSize; ++i ){
		int flag = 0;
		for(int j = 0; j < numsSize; ++j ){
			if( i == j ){
				continue;
			}
			if( nums[i] == nums[j] ){
				flag = 1;
				break;
			}
		}
		if( flag != 1 ){
			break;
		}
        ++num;
	}
	return nums[num];
}

排序法原理:

//1、先采用排序算法将数组进行由小到大排序,此处可以用冒泡排序或快速排序
//2、然后对比前后两个元素是否一样
//例如:  
for(int i=0;i<sizeof(nums)/sizeof(nums[0];i+=2)){
	if(nums[i]!=nums[i+1])break;
	if(i+1>=numsSize)break; 	
}
//3、返回下标 i 对应的元素
4、只出现一次的数字 II

做法:(暴力枚举/记录法/排序法/索引法//三进制异或操作)

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:
输入: [2,2,3,2]
输出: 3

示例 2:
输入: [0,1,0,1,0,1,99]
输出: 99

int singleNumber(int* nums, int numsSize){
    int i,j,k,flag=0;
    if(numsSize==1)
        return nums[0];
    for(i=0;i<numsSize;i++)
    {
        for(j=0;j<numsSize;j++)
        {
            if(nums[i]==nums[j]&&i!=j)
            {
                flag=0;
                break;
            }
            else if(nums[i]!=nums[j])
            {
                k=nums[i];
                flag=1;
            }
        }
        if(flag==1)
            break;
    }
    return k;
}
//排序法,使用qsort()函数进行快速排序,然后三指针滑窗对比
int cmp(const void *a, const void *b)
{
    return *((int*)a) > *((int *)b);
}
int singleNumber(int* nums, int numsSize){
    qsort(nums, numsSize, sizeof(int), cmp);
    int i;
    for (i = 0; i < numsSize; i += 3) {
        if (i + 1 >= numsSize) break;
        if (nums[i] != nums[i+1]) break;
    }
    return nums[i];
}

三进制异或:
由于计算机的异或默认是二进制的,而二进制的异或是将元素的每位按位相加然后对2取余(满二不进位),所以采用三进制的异或需要将元素的每位按位相加然后对3取余(满三不进位)。

5、缺失数字

做法: (暴力枚举/数组索引/二进制异或操作)

给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。

示例 1:
输入: [3,0,1]
输出: 2

示例 2:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8

//二进制异或   将nums中的元素对0~numsSize进行异或,得出0~numsSize中缺失的元素。
int missingNumber(int* nums, int numsSize){
    int xor = 0;
    for (int i = 0; i < numsSize; i++) {
        xor ^= nums[i];
        xor ^= i;
    }
    xor ^= numsSize;
    return xor;
}
/*
思路2:对数组进行排序(从小到大),然后从0开始循环,判断nums中的值是否等于下标
*/
int cmp(const void *a, const void *b)
{
    return *((int*)a) > *((int *)b);
}
int missingNumber(int* nums, int numsSize){
    int i = 0;

    qsort(nums, numsSize, sizeof(int), cmp);

    for (i = 0; i < numsSize; i++) {
        if (nums[i] != i) {
            return i;
        }
    }
    //如果没有找到,说明缺失的最后一个值
    return i;
}
发布了55 篇原创文章 · 获赞 14 · 访问量 3365

猜你喜欢

转载自blog.csdn.net/weixin_41969690/article/details/103731091