分享一些刷题中遇到的又多种解法的题目
题目链接
使用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;
}
创建两个数组,一个用于输入字符串,
另外再开辟一个数组,元素个数为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;
}
太神奇了,完全没想到这种方法。
题目链接
遍历数组,计算某个元素在数组中出现的次数,判断是否大于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;
}
这道题其实求的就是众数(出现次数最多的数字),所以我们只需要将数组进行排序,再返回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];
}
题目链接
创建两个数组:
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;
}
先创建两个变量分别从左侧和右侧开始乘以给定的数组
之后,再赋给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;
}
题目链接
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,就是结果
int Add(int num1, int num2)
{
return (num1 | num2) + (num1 & num2);
}
二者相或,结果是所有非0的位之和
二者相与,是之前或运算中漏算的1
二者相加得出的就是二者的和
解释:
因为二进制中,不是1就是0
先用或运算,找出所有的1
再通过与运算,找出漏下的1
输入一个数字,倒叙打印这个数字
如,输入123
打印出321
#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”) 把输入的数字当做一个字符串进行接收,然后直接从后向前倒序输出。
#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");
}
这个系列的文章具体几道题没有标准,就差不多我写四五道题就发一篇
希望这篇文章对你有帮助,我们下次见~