C语言每日一题:4.消失的数字+数字在升序数组中出现的次数+整数转换

请添加图片描述
消失的数字:

思路1:排序+遍历
1.使用qsort排序数组判断当前数值+1是否是数组下一个元素的数值。
2.如果是一直循环注意数组越界,如果不是那么当前的数组的数值+1就是消失的数。
3.存在0——n的数字是第n个数没有了。循环过程中从头到尾也找不到这个数字。
4.因为在循环过程中数组下标只会从0到n-1.前面排序之后都满足循环要求。
5.在循环判断之前判断一下num[n-1]+1是否等于n;如果等于说明是最大的数值消失直接返回。
6.如果不是进入循环找这个数值。

int cmp(void* a, void* b)
{
    return (*((int*)a) - *((int*)b));
}

int missingNumber(int* nums, int numsSize)
{
	//排序+遍历的方法
    qsort(nums, numsSize, sizeof(nums[0]), cmp);
    int i = 0;
    int ret = 0;
    int flag = -1;
    if ((nums[numsSize - 1] + 1) == numsSize)
    {
        flag = 0;
    }
    //都不是最大数值失去的情况。
    else
    {
       //注意数组越界
       while (i < numsSize - 1)
        {
            if ((nums[i] + 1 == nums[i + 1]) && (nums[0] == 0))
            {
                i++;
            }
            //第一位不是0说明0消失了
            else if (nums[0] != 0)
            {
                ret = 0;
                break;
            }
            else
            {
                ret = nums[i] + 1;
                break;
            }
        }
    }
     if (flag == 0)
    {
        return numsSize;
    }
    return ret;

思路二:使用计算的方法
1.定义sum1和sum2分别作为0到n所有数值的和,和0到n除了消失数字的和。
2.计算sum1直接使用等差数列求和,((0+numsize)*(numsize+1))/2
3.计算sum2直接遍历求和。(防止数组越界)。加numsize次。


int missingNumber(int* nums, int numsSize)
{
    //计算数值差的方法
    int sum1=0;
    int sum2=0;
    sum2=((0+numsSize)*(numsSize+1))/2;
    for(int i=0;i<numsSize;i++)
    {
        sum1+=nums[i];
    }
    return sum2-sum1;
}

思路三:按位与的思路
1.定义一个x,先与数组中的每一个内容按位与。
2.然后x再与,0到n的所有数值进行按位与。
3.按位与满足交换律(相同的数消除)
比如:0,1,2,3,4,5
: 0,1,2,3,4,5,6
按位与之后结果是6.

int missingNumber(int* nums, int numsSize)
{

    int x=0;
    
     for(int i=0;i<numsSize;i++)
    {
        x^=nums[i];
    }
    for(int i=0;i<=numsSize;i++)
    {
        x^=i;
    }
    return x;

请添加图片描述

数字在升序数组中出现的次数

数字在升序数组中出现的次数
思路1:
1.这个K只出现一次,或者出现多次。
2.这个K没有出现过。
3.二分查找的思路。
4.当查找结束,判断arr[mid]==k吗?,不等于说明这个k不存在于这个数组里面我们直接返回0;
5.找到了这个K数的位置我们mid下标向右移动直到下一个不是停止到k的位置停止,左边同理。
6.同时记录K的数值。

int GetNumberOfK(int* nums, int numsLen, int k)
{
    // write code here
    if (numsLen == 0)
    {
        return 0;
    }
    //出现一次(mid这个位置确实是出现了一次)and没有出现
    int left = 0;
    int right = numsLen - 1;
    int mid = 0;
    while (left <= right)
    {
        mid = (left + right) / 2;
        if (nums[mid] < k)
        {
            left = mid + 1;
        }
        else if (nums[mid] > k)
        {
            right = mid - 1;
        }
        else
        {
            break;
        }
    }

    //这个数值不存在
    if (nums[mid] != k)
    {
        return 0;
    }


    //只有一个数,这一个就是要的
    int count = 1;
    if (nums[mid] == k && numsLen == 1)
    {
        return 1;
    }
    
    else if(nums[mid] == k && numsLen != 1)
    {
        int left=mid;
        int right=mid;
            while (nums[right + 1] == k)
            {
                right++;
                count++;
            }
            
            while (nums[left - 1] == k)
            {
                left--;
                count++;
            }     
    }
 return count;
}

请添加图片描述

整数转换

思路1:
1.注意A,B的范围。在二进制位上31个是数值位,一位是符号位。
2.我们可以通过按位异或的方式拿出不同位数的情况。
3.变成了记录按位异或结果中1的数值个数。
4.b=1<<i 判断异或结果&b是否==b相等就说明对应异或结果处的值为1.
5.A,B 。有三种情况:
1.A,B中有一个为负数,所以需要加上符号位的1.
2.A,B同正或者同负,直接返回统计的结果。

int convertInteger(int A, int B){
    //两个数值进行按位异或
    int C=A^B;
    //进行记录
    int count=0;
    int b=0;
    if(((A<0)||(B<0)))
    {
        count+=1;
    }
    for(int i=0;i<31;i++)
    {
        b=(1<<i);
        if((b&C)==b)
        {
            count++;
        }
    }
    if((A<0)&&(B<0))
    count--;

    return count;

}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值