【C语言】题目的多种解法分享3

前言

分享一些刷题中遇到的又多种解法的题目

1:HJ10 字符个数统计

题目

题目链接

解法:

解法1:使用qsort

使用qsort进行排序,再遍历数组,对数组的每个元素判断是否相等,相等将其赋值为0~127范围以外的数字,
之后再遍历一遍数组判断,看其是否为范围外的数字即可

#include
#include
#include

int cmp(const void* p1, const void* p2)
{
	return *(char*)p1 - *(char*)p2;
}

int main()
{
	char arr[501] = { 0 };
	scanf("%s", &arr);
	qsort(arr, strlen(arr), sizeof(char), cmp);
	int i = 0;
	int sum = 0;

	for (i = 0; i < strlen(arr); i++)
	{
		if (arr[i] == arr[i + 1])
		{
			arr[i] = -1;
		}

	}
	for (i = 0; i < strlen(arr); i++)
	{
		if (arr[i] != -1)
		{
			sum++;
		}
	}
	printf("%d\n", sum);
	return 0;
}

解法2:创建两个数组

创建两个数组,一个用于输入字符串,
另外再开辟一个数组,元素个数为128:对应着0~127共128个数字

剩下的解释我写在了注释里

#include 
#include 

int num=0,len,i,j,k,asc;
int tmp[128]={0};
char str[400];
int main()
{
    gets(str);
    len=strlen(str);
    for(i=0;i<len;i++)
    {
        asc=(int)str[i];//将字符强制转换成它的ASCII码值,赋值给asc
        if(tmp[asc]==0)//将asc作为下标,
        //如果数组中,该下标处的元素为0,那么asc就在0~127之间,也就是str[i]符合条件
        {
            tmp[asc]=1;
            num++;
        }
    }
    printf("%d",num);
    return 0;
}

太神奇了,完全没想到这种方法。

2:169. 多数元素

题目

题目链接

解法1:遍历

遍历数组,计算某个元素在数组中出现的次数,判断是否大于n/2

int majorityElement(int* nums, int numsSize)
{
	int i = 0;
	int j = 0;
	int sum = 0;
	for (i = 0; i < numsSize; i++)
	{
		for (j = 0; j < numsSize; j++)
		{
			if (nums[i] == nums[j])
			{
				sum++;
			}
			if (sum > (numsSize / 2))
			{
				return nums[i];
			}
		}
		
	}
	return 0;
}

解法2:使用qsort

这道题其实求的就是众数(出现次数最多的数字),所以我们只需要将数组进行排序,再返回n/2下标处的元素即可

注意:

因为题目已经明确说明:

假设数组是非空的,并且给定的数组总是存在多数元素。

所以我们不需要考虑是否该元素出现次数不足n/2

当然,我们也可以将取出的这个元素和排序后的数组首元素进行比较,相等则为众数

代码:

int cmp(const void* p1, const void* p2)
{
	return *(int*)p1 - *(int*)p2;
}

int majorityElement(int* nums, int numsSize)
{
	qsort(nums, numsSize, sizeof(int), cmp);
	return nums[numsSize / 2];

}

3:238. 除自身以外数组的乘积

题目

题目链接

解法

解法1:创建两个数组计算左边和右边

创建两个数组:

	int left[numsSize];
	int right[numsSize];

注意:
这里使用的是变长数组,VS不支持这种写法

left数组用于记录i左侧的元素之积

left[0] = 1;
for (int i = 1; i < numsSize; i++)
{
	left[i] = left[i - 1] * nums[i - 1];
}

right数组用于记录i右侧的元素之积

	right[numsSize - 1] = 1;
	for (i = numsSize - 1 - 1; i >= 0; i--)
	{
		right[i] = right[i + 1] * nums[i + 1];
	}

注意:
这里要从最右侧开始,

最后再利用循环将两个数组乘在一起

for (i = 0; i < numsSize; i++)
{
	returnNums[i] = left[i] * right[i];
}

代码

int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{
	int left[numsSize];
	int right[numsSize];


	int i = 1;

	left[0] = 1;
	for (i = 1; i < numsSize; i++)
	{
		left[i] = left[i - 1] * nums[i - 1];
	}

	right[numsSize - 1] = 1;
	for (i = numsSize - 1 - 1; i >= 0; i--)
	{
		right[i] = right[i + 1] * nums[i + 1];
	}

	*returnSize = numsSize;
	int* returnNums = (int*)malloc(sizeof(int) * numsSize);

	for (i = 0; i < numsSize; i++)
	{
		returnNums[i] = left[i] * right[i];
	}
	return returnNums;
}

解法2:创建一个数组遍历

先创建两个变量分别从左侧和右侧开始乘以给定的数组
之后,再赋给arr

int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{

	int i = 0;
	int *arr = (int*)malloc(sizeof(int)* numsSize);
	for(i = 0; i < numsSize; i++)
	{
        arr[i] = 1;
  	}
 
	int pre = 1;
	int suf = 1;

	for (i = 1; i < numsSize; i++)
	{
		pre *= nums[i - 1];
		suf *= nums[numsSize - i];
		arr[i] *= pre;
		arr[numsSize - 1 - i] *= suf;
	}
	*returnSize = numsSize;
	
	return arr;

}

4:JZ65 不用加减乘除做加法

题目

题目链接

解法

解法1

int Add(int num1, int num2)
{
	int m = 0;
	int n = 0;
	m = (num1 & num2);
	m <<= 1;
	n = num1 ^ num2;
	while (n & m)
	{
		num1 = m;
		num2 = n;

		m = (num1 & num2);
		m <<= 1;
		n = num1 ^ num2;
	}
	return m | n;

}

解释:

m是二者与运算之后的结果,都是需要进位的,
所以m<<1
n是二者中不同的位,也就是不需要进位的

当m&n不为0,也就是进位没进干净之前,都要在while循环中重复上面的操作,

最后返回m | n,就是结果

解法2

int Add(int num1, int num2) 
{
	return (num1 | num2) + (num1 & num2);

}

num1 | num2

二者相或,结果是所有非0的位之和

num1 & num2

二者相与,是之前或运算中漏算的1

二者相加得出的就是二者的和

解释:
因为二进制中,不是1就是0
先用或运算,找出所有的1
再通过与运算,找出漏下的1

5:倒序输出数字

题目

输入一个数字,倒叙打印这个数字
如,输入123
打印出321

解法

解法1:当成字符串输入

#include 
int main()
{
    char str[32] = {0};
    scanf("%s",str);
    //gets(str);
    for(int i=strlen(str)-1;i>=0;i--)
    {
        printf("%c",str[i]);
    }
    printf("\n");
}

可以通过 scanf(“%s”) 把输入的数字当做一个字符串进行接收,然后直接从后向前倒序输出。

解法2:当成数字输入

#include
int main(){
    int num = 0;
    scanf("%d\n",&num);
    if(num == 0) 
    {	
    	printf("%c",'0');
    }
    while(num != 0)
    {
        printf("%c",num%10+'0');
        num/=10;
    }
    printf("\n");
}

结语

这个系列的文章具体几道题没有标准,就差不多我写四五道题就发一篇

希望这篇文章对你有帮助,我们下次见~

你可能感兴趣的:(C语言多种解法分享,c语言,开发语言)