【小嘟陪你刷题01】LeetCode 448 238 728 724 349 747 面试题05.06 645

2023-11-23 18:20

本文主要是介绍【小嘟陪你刷题01】LeetCode 448 238 728 724 349 747 面试题05.06 645,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 前言
  • 1、LeetCode 448 找到所有数组中消失的数字
    • 思路:原地修改
    • 代码示例:
  • 2、LeetCode 238 除自身以外数组的乘积
    • 思路:乘积 = 当前数左边的乘积 * 当前数右边的乘积
    • 代码示例:
  • 3、LeetCode 728 自除数
    • 思路:直接判断
    • 代码示例:
  • 4、LeetCode 169 多数元素
    • 思路:排序
    • 代码示例:
  • 5、LeetCode 724 寻找数组的中心下标
    • 思路:前缀法
    • 代码示例:
  • 6、LeetCode 349 两个数组的交集
    • 思路:排序+双指针
    • 代码示例:
  • 7、LeetCode 747 至少是其他数字两倍的最大值
    • 思路:遍历
    • 代码示例:
  • 8、LeetCode 面试题05.06.整数转换
    • 思路:异或
    • 代码示例:
  • 9、LeetCode 645 错误的集合
    • 思路:排序
    • 代码示例:
  • 总结

前言

此篇文章是刷题系列的第一篇,此后该系列会随着小嘟对语言知识的学习而改变语言的使用!刚开始是用C语言来解决哦~可能顺序有些复杂,再加上数据结构的使用不熟练,还请大家见谅!
方法可能并不是小嘟想出来的,但还是想能够分享给大家!让更多的人知道!

1、LeetCode 448 找到所有数组中消失的数字

在这里插入图片描述

思路:原地修改

我们可以用一个哈希表记录数组nums中的数字,由于数字范围均在[1,n]中,记录数字后我们再利用哈希表检查[1,n]中的每一个数是否出现,从而找到缺失的数字。

由于数字范围均在 [1,n]中,我们也可以用一个长度为 nn 的数组来代替哈希表。这一做法的空间复杂度是 O(n) 的。我们的目标是优化空间复杂度到 O(1)。

注意到nums 的长度恰好也为 n,能否让nums 充当哈希表呢?

由于nums 的数字范围均在 [1,n]中,我们可以利用这一范围之外的数字,来表达「是否存在」的含义。

具体来说,遍历nums,每遇到一个数 x,就让 nums[x−1] 增加 n。由于 nums 中所有数均在 [1,n] 中,增加以后,这些数必然大于 n。最后我们遍历 nums,若 nums[i] 未大于 n,就说明没有遇到过数 i+1。这样我们就找到了缺失的数字。

注意,当我们遍历到某个位置时,其中的数可能已经被增加过,因此需要对 n 取模来还原出它本来的值。

可能讲的有点抽象,小嘟画一张图帮助理解吧!
此处举例以[1,2,2,3,3,4,7,8]来帮助理解!
在这里插入图片描述
像这样就找出来下标为4,5的数值小于numsSize了,我们只需要把这两个下标+1赋给新的数组就可以了!

代码示例:

int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){int i = 0;int x = 0;for (i = 0; i < numsSize; i++) {x = (nums[i] - 1) % numsSize;nums[x] += numsSize;}int* findDisappearedNumbers = (int*)malloc(sizeof(int) * numsSize);*returnSize = 0;for (i = 0; i < numsSize; i++) {if (nums[i] <= numsSize) {findDisappearedNumbers[(*returnSize)++] = i + 1;}}return findDisappearedNumbers;}

2、LeetCode 238 除自身以外数组的乘积

在这里插入图片描述

思路:乘积 = 当前数左边的乘积 * 当前数右边的乘积

如标题一样:乘积 = 当前数左边的乘积 * 当前数右边的乘积
举个例子:
在这里插入图片描述
像这样就能够实现题目的要求了!

代码示例:

int* productExceptSelf(int* nums, int numsSize, int* returnSize){int* productExceptSelf = (int*)malloc(sizeof(int) * (numsSize));int i = 0;int k = 1;for(i = 0; i < numsSize; i++){productExceptSelf[i] = k;k *= nums[i]; }k = 1;for(i = numsSize- 1; i >= 0; i--){productExceptSelf[i] *= k; k *= nums[i]; }* returnSize = numsSize;return productExceptSelf;}

3、LeetCode 728 自除数

在这里插入图片描述

思路:直接判断

遍历范围 [left,right] 内的所有整数,分别判断每个整数是否为自除数。

根据自除数的定义,如果一个整数不包含 0 且能被它包含的每一位数整除,则该整数是自除数。判断一个整数是否为自除数的方法是遍历整数的每一位,判断每一位数是否为 0 以及是否可以整除该整数。

遍历整数的每一位的方法是,每次将当前整数对 10 取模即可得到当前整数的最后一位,然后将整数除以 10。重复该操作,直到当前整数变成 0时即遍历了整数的每一位。
在这里插入图片描述

代码示例:

 int isSelfDividing(int num){int temp = num;while (temp > 0) {int digit = temp % 10;if (digit == 0 || num % digit != 0) {return 0;}temp /= 10;}return 1;}
int* selfDividingNumbers(int left, int right, int* returnSize){int * selfDividingNumbers = (int *)malloc(sizeof(int) * (right - left + 1)); int i = 0;int pos = 0;for(i = left; i <= right; i++){if(isSelfDividing(i)){selfDividingNumbers[pos++] = i;}}* returnSize = pos;return selfDividingNumbers;
}

4、LeetCode 169 多数元素

在这里插入图片描述

思路:排序

这是一种简单的方法:
如果将数组nums中的所有元素按照递增或者递减的顺序排序,那么下标为[n/2]的元素(下标从0开始)一定是众数。
在这里插入图片描述

代码示例:

int cmp(const void *e1,const void *e2)
{return *(int*)e1 - *(int*)e2;
}
int majorityElement(int* nums, int numsSize){qsort(nums,numsSize,sizeof(int),cmp);return nums[numsSize / 2];
}

5、LeetCode 724 寻找数组的中心下标

在这里插入图片描述

思路:前缀法

记数组的全部元素之和为total,当遍历到第 ii 个元素时,设其左侧元素之和为 sum,则其右侧元素之和为total−numsi−sum。左右侧元素相等即为sum=total−numsi−sum,即2×sum+numsi=total。

当中心索引左侧或右侧没有元素时,即为零个项相加,这在数学上称作「空和」(empty sum)。在程序设计中我们约定「空和是零」。

代码示例:

int pivotIndex(int* nums, int numsSize){int total = 0;for (int i = 0; i < numsSize; i++) {total += nums[i];}int sum = 0;for (int i = 0; i < numsSize; i++) {if (2 * sum + nums[i] == total) {return i;}sum += nums[i];}return -1;}

6、LeetCode 349 两个数组的交集

在这里插入图片描述

思路:排序+双指针

如果两个数组是有序的,则可以使用双指针的方法得到两个数组的交集。

首先对两个数组进行排序,然后使用两个指针遍历两个数组。可以预见的是加入答案的数组的元素一定是递增的,为了保证加入元素的唯一性,我们需要额外记录变量pre 表示上一次加入答案数组的元素。

初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,如果两个数字相等,且该数字不等于 pre ,将该数字添加到答案并更新pre 变量,同时将两个指针都右移一位。当至少有一个指针超出数组范围时,遍历结束。
举个例子:
在这里插入图片描述

代码示例:

int cmp(void* a, void* b) {return *(int*)a - *(int*)b;
}
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){qsort(nums1, nums1Size, sizeof(int), cmp);qsort(nums2, nums2Size, sizeof(int), cmp);*returnSize = 0;int index1 = 0, index2 = 0;int* intersection = malloc(sizeof(int) * (nums1Size + nums2Size));while(index1 < nums1Size && index2 < nums2Size){int num1 = nums1[index1];int num2 = nums2[index2];if(num1 == num2){if(!(*returnSize) || num1 != intersection[(*returnSize) - 1]){intersection[(*returnSize)++] = num1; }index1++;index2++;}else if(num1 < num2){index1++;}else{index2++;}}return intersection;
}

7、LeetCode 747 至少是其他数字两倍的最大值

在这里插入图片描述

思路:遍历

遍历数组分别找到数组的最大值m1和次大值m2 。如果 m1 ≥m2 × 2 成立,则最大值至少是数组其余数字的两倍,此时返回最大值的下标,否则返回−1。
为了返回最大值的下标,我们需要在计算最大值的同时记录最大值的下标。

代码示例:

int dominantIndex(int* nums, int numsSize){if(numsSize == 1){return 0;}int a = -1, b = 0;for(int i = 1; i < numsSize; i++){if (nums[i] > nums[b]){a = b; b = i;} else if (a == -1 || nums[i] > nums[a]) {a = i;}}return nums[b] >= (nums[a] * 2) ? b : -1;}

8、LeetCode 面试题05.06.整数转换

在这里插入图片描述

思路:异或

1.异或
2.统计二进制个数:
首先把n &(按位与)1,判断n的最低位是不是1,
接着把1左移一位得到2 ,再 &(按位与)n,
就能判断n的次第位是不是为1
反复左移运算,每次都能判断n的其中一位是不是1。

代码示例:

int convertInteger(int A, int B){int i = 0;int count = 0;int tmp = A ^ B;for(i = 0; i < 32; i++){if((tmp>>i)&1 == 1){count++;}}return count;
}

9、LeetCode 645 错误的集合

在这里插入图片描述

思路:排序

在这里插入图片描述

代码示例:

int cmp(int* a, int* b) {return *a - *b;
}int* findErrorNums(int* nums, int numsSize, int* returnSize) {int* errorNums = malloc(sizeof(int) * 2);*returnSize = 2;qsort(nums, numsSize, sizeof(int), cmp);int prev = 0;for (int i = 0; i < numsSize; i++) {int curr = nums[i];if (curr == prev) {errorNums[0] = prev;}else if (curr - prev > 1) {errorNums[1] = prev + 1;}prev = curr;}if (nums[numsSize - 1] != numsSize) {errorNums[1] = numsSize;}return errorNums;
}

总结

今天就先到这了,如果大家对某些题有着更好的解法,欢迎在评论区进行讨论哦~

这篇关于【小嘟陪你刷题01】LeetCode 448 238 728 724 349 747 面试题05.06 645的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/419840

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

荣耀嵌入式面试题及参考答案

在项目中是否有使用过实时操作系统? 在我参与的项目中,有使用过实时操作系统。实时操作系统(RTOS)在对时间要求严格的应用场景中具有重要作用。我曾参与的一个工业自动化控制项目就采用了实时操作系统。在这个项目中,需要对多个传感器的数据进行实时采集和处理,并根据采集到的数据及时控制执行机构的动作。实时操作系统能够提供确定性的响应时间,确保关键任务在规定的时间内完成。 使用实时操作系统的

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

一些其他面试题

阿里二面:那你来说说定时任务?单机、分布式、调度框架下的定时任务实现是怎么完成的?懵了。。_哔哩哔哩_bilibili 1.定时算法 累加,第二层每一个格子是第一层的总时间400 ms= 20 * 20ms 2.MQ消息丢失 阿里二面:高并发场景下引进消息队列有什么问题?如何保证消息只被消费一次?真是捏了一把汗。。_哔哩哔哩_bilibili 发送消息失败

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

集中式版本控制与分布式版本控制——Git 学习笔记01

什么是版本控制 如果你用 Microsoft Word 写过东西,那你八成会有这样的经历: 想删除一段文字,又怕将来这段文字有用,怎么办呢?有一个办法,先把当前文件“另存为”一个文件,然后继续改,改到某个程度,再“另存为”一个文件。就这样改着、存着……最后你的 Word 文档变成了这样: 过了几天,你想找回被删除的文字,但是已经记不清保存在哪个文件了,只能挨个去找。真麻烦,眼睛都花了。看