力扣网C语言编程题:涉及数组的题目

发布于:2025-06-23 ⋅ 阅读:(107) ⋅ 点赞:(0)

一. 简介

本文记录力扣网上编程题目,主要涉及数组方面的,以 C语言实现。

二. 力扣网C语言编程题:只出现一次的数字

题目: 只出现一次的数字

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

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

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

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

示例 3 :
输入:nums = [1]
输出:1

提示:
    1 <= nums.length <= 3 * 104
    -3 * 104 <= nums[i] <= 3 * 104
    除了某个元素只出现一次以外,其余每个元素均出现两次。

题目分析:

数组中有一个元素只出现一次,剩下的其他元素都是出现两次,这里查找出现一次的元素。

首先第一种比较笨的办法就是暴力解法。遍历数组元素,数组每个元素与其他元素进行比较,找到出现一次的元素。

其次可以考虑使用哈希表。哈希表有键key 和 value,可以将元素值作为key,出现次数作为 value,最后统计次数。

解题思路一:(暴力解法)

遍历数组元素,数组每个元素与其他元素进行比较,找到出现一次的元素。那么每个元素都要跟数组中所有元素比较一次,则需要双层循环实现。

时间负责度为O(n*n),空间负责度为 O(1);

C语言实现如下:

int singleNumber(int* nums, int numsSize) {
    int i,j;
    int data = 0;

    for(i = 0; i < numsSize; i++) {
        for(j = 0; j < numsSize; j++) {
            if((nums[i] == nums[j]) && (i != j)) {
                break;
            }

            if(j == numsSize-1) {
                data = nums[i];
            }
        }
    }

    return data;
}

可以看出,暴力解决方法的时间复杂度为O(n*n),不满足要求。

解题思路二:(哈希表)

1. 遍历数组,求数组中最大值和最小值,创建哈希表数组;

2. 遍历哈希表数组,统一每个元素出现次数;

3. 遍历哈希表数组,查找出现一次的元素;

可以估算出该方法的时间复杂度为 O(n),哈希表需要跟数组元素创建一个,则空间复杂度为O(n);

C语言实现如下:


int singleNumber(int* nums, int numsSize) {
    int i = 0;
    int max = 0, min = 0;

    for(i = 0; i < numsSize; i++) {
        min = min > nums[i]?  nums[i]:min;
        max = max < nums[i]?  nums[i]:max;
    }
    
    int n = max-min+1;
    int hash_table[n];
    memset(hash_table, 0, sizeof(hash_table));
    for(i = 0; i < numsSize; i++) {
        hash_table[nums[i]-min] += 1;
    }

    for(i = 0; i < numsSize; i++) {
        if(hash_table[nums[i]-min]  == 1) {
            return nums[i];
        }
    }
    return 0;
}

哈希表解决方法的空间复杂度都不满足要求。

解题思路三:(位运算)

解题思路三考虑使用位运算,使用 "^"(异或)运算。

首先,了解下 "异或"运算的特点:

0 ^ 任何数 == 任何数  // 0和 任何数进行异或运算,结果是任何数
a ^ a == 0           //表示任何数和自己进行 异或运算都为0

//异或操作满足交换律和结合律
a ^ b ^ a  == a ^ a ^ b  == (a ^ a)^ b == b    

那么,数组中只有一个数字出现了一次,剩下的元素都出现了两次,也就说,遍历数组元素一遍,那么所有元素进行一轮异或运算之后,最后得到的数字就是出现一次的元素(出现两次的元素经过异或运算之后就为0了,相互抵消了);

C语言实现如下:

int singleNumber(int* nums, int numsSize) {
    int i = 0;
    int data = nums[0];
    
    while(i < numsSize) {
        data = data ^ nums[i];
        i++;
    }
    return data;
}

可以看出,位运算方法的时间复杂度为 O(n),空间复杂度为 O(1)。满足了题目要求。