文章目录
-
一.只出现一次的数字
-
二.模拟实现aoti函数
-
三.两个数组的交集
一、只出现一次的数字
给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。
来源:力扣(LeetCode)
方法一:
这道题的具体思路就是用异或的思想来解决。
什么是异或:对于两个数字,相同为0,相异为1异或的性质:
- 交换律: a ^ b ^ c == a ^ c ^ b
- 任何数与0异或都得任何数
- 相同的数异或为0
#include <stdio.h>
int main() {
int* num=(int*)malloc(sizeof(int)*2);
int arr[] = {1, 2, 1, 3, 4, 4, 5, 7, 7,6};
int len = sizeof(arr) / sizeof(arr[0]);
int ret = 0;
for(int i = 0; i < len; i ++) {
ret ^= arr[i];
}
printf("%d \n", ret);
//ret就是5^6的结果,二进制中一定有1
//计算ret的第几位是1
int pos = 0;
for(int i = 0; i < 32; i ++) {
if(((ret >> i) & 1) == 1) {
pos = i;
break;
}
}
//ret的第pos位是1
//把arr数组中的每个元素的pos位为1的数字异或在一起
for(int i = 0; i < len; i ++) {
if(((arr[i] >> pos) & 1) == 1) {
num[0] ^= arr[i];
}else {
num[1] ^= arr[i];
}
}
printf("%d %d ", num[0], num[1]);
return 0;
}
方法二:
1.初始化(*returnSize)=0;
2.申请分配动态内存;
3.设置计数器
4.用双指针遍历数组;
5.将出现次数为1的元素放置于动态内存中;
6.返回结果.
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* singleNumber(int* nums, int numsSize, int* returnSize){
(*returnSize)=0;
int* ret=malloc(sizeof(int) * numsSize);//分配动态内存
int i,j,count;//count计数
for(i=0;i<numsSize;i++)
{
count=0;//计数器初始化
for(j=0;j<numsSize;j++)
{
if(nums[i]==nums[j])
count++;
}
if(count==1)
ret[(*returnSize)++]=nums[i];
}
return ret;
}
二、模拟实现aoti函数
这个函数的主要功能就是将字符串的数字转换为数字。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
//
//my_atoi(NULL)//异常
//my_atoi("")//异常
//my_atoi(" +123")//正常
//my_atoi("-123")//正常
//my_atoi("123abc")//异常
//my_atoi("1111111111111111111111111")//异常
//my_atoi("-1111111111111111111111111")//异常
enum Status {
VALID,
INVALID
};
enum Status status = INVALID;
int my_aoti(char* str) {
if (str == NULL) {
return 0;
}
if (*str == '\0') {
return 0;
}
//空白字符
while (isspace(*str)) {
str++;
}
int flag = 1;
if (*str == '+') {
flag = 1;
str++;
}
else if (*str == '-') {
flag = -1;
str++;
}
//处理数字字符
long long ret = 0;
while (isdigit(*str)) {
ret = ret * 10 + flag * (*str - '0');
if (ret < INT_MIN || ret > INT_MAX) {
return 0;
}
str++;
}
if (*str == '\0') {
status = VALID;
return (int)ret;
}
else {
status = VALID;
return (int)ret;
}
}
int main() {
//我们首先要有能力解决上面的几个异常
int ret = my_aoti("123");
if (status = VALID) {
printf("非法的转换:%d", ret);
}
else {
printf("合法的转换:%d", ret);
}
}
三. 两个数组的交集
给定两个数组
nums1
和nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
static int arr[1000];
*returnSize=0;
int i,j,k;
for(i=0;i<nums1Size;i++){
for(j=0;j<nums2Size;j++){
if(nums2[j] == nums1[i]) break;
}
if(j == nums2Size){
continue;
}
for(j=0;j<*returnSize;j++){
if(nums1[i] == arr[j]) break;
}
if(j == *returnSize){
arr[*returnSize] = nums1[i];
*returnSize += 1;
}
}
return arr;
}