Topic description
In an array nums
all but one number appears three times. Please find the number that occurs only once.
Example 1:
输入: nums = [3,4,3,3]
输出: 4
Example 2:
输入: nums = [9,1,7,9,7,9,7]
输出: 1
The original title address of Leetcode: https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/
Thought analysis
Number of occurrences using object stats
The idea is in two steps:
- The first step is to count the number of occurrences of the value
- The second step is to see who appears the number of times
var singleNumber = function (nums) {
/** 第一步 统计值出现的次数 */
let obj = {} // 1. 定义一个对象用来存储 '谁' 出现了 '几次'
for (let i = 0; i < nums.length; i++) {
if (nums[i] in obj) { // 2. 若对象中有,就把对应次数加一,当然一开始是没有的
obj[nums[i]] = obj[nums[i]] + 1 // 4. 比如{9:1} 变成了 {9:2} 由原来的一次,变成两次了
} else {
obj[nums[i]] = 1 // 3. 本来是空对象,现在变成{9:1} 后续若还出现9 就次数加一,变成{9:2}
}
}
/** 第二步,看看谁出现的次数是一次 */
for (const key in obj) {
if (obj[key] == 1) {
return key
}
}
};
Note the obj count: we take nums = [3,4,3,3]
as an example, then the obj becomes {3:3,4:1}
Count the number of occurrences of a number using the Map collection
This method is similar to the object method in that it stores the number of occurrences of the corresponding item. The code is as follows:
var singleNumber = function (nums) {
/** 第一步 统计值出现的次数 */
let map = new Map() // 1. 定义一个Map集合来存储
for (let i = 0; i < nums.length; i++) {
if (map.has(nums[i])) { // 2. 若Map集合中有,就把对应次数加一,当然一开始是没有的
let count = map.get(nums[i]) // 4. 有的话,先看看次数是几
map.set(nums[i], count + 1) // 5. 然后看把次数加上一即可
} else {
map.set(nums[i], 1) // 3. 没有就存一份
}
}
/** 第二步,看看谁出现的次数是一次 */
for (const [key, value] of map.entries()) { // 6. 最后再遍历看看谁出现的次数是1
if (value == 1) {
return key // 就把谁返回即可
}
}
};
Think about it, can you use an array to record the number of times who appears? In fact, arrays can also be used here to solve. However, you need to make a two-dimensional array, because there are two variables, 谁、对应谁出现的次数
You can try it according to this idea, it is similar with little difference
Check if the current item does not appear in the rest of the array
The idea is very simple, for example: the original array [6,5,5,5]
split the original array into [6],[5,5,5,]
see if 6
appears in the rest of the array, if not The rest of the array appears again, indicating that 6
only appears once, indicating that we are looking for this one 6
. code show as below:
var singleNumber = function (nums) {
for (let i = 0; i < nums.length; i++) {
let copyNums = nums.slice(0) // 1. 拷贝一份原数组
copyNums.splice(i, 1) // 2. 拿到除去当前项以外余下项组成的数组
let remainNums = copyNums // 3. 得到余下的数组
if (!remainNums.includes(nums[i])) { // 4. 若当前项在余下的数组中没有再一次出现
return nums[i] // 5. 说明就是它啦
}
}
};
However, this method is not very good, and the array method is used a bit more, so the performance is not very high. I mention it here, just to give you some ideas
Determine whether the start index of the current item is equal to the end index
Ideas: As far as the current topic is concerned, the rules can be defined like this, for example an array: [5,5,6,5]
. Because there is only one 6
, so 6
the index of the first occurrence of the position is 2
the index of the last occurrence is also 2
Whether the position of the first occurrence of an item is equal to the position of the last occurrence of an item is sufficient. The code is as follows:
var singleNumber = function (nums) {
for (let i = 0; i < nums.length; i++) {
let firstTimeIndex = nums.indexOf(nums[i]) // 1. 找到首次出现的位置
let lastTimeIndex = nums.lastIndexOf(nums[i]) // 2. 找到最后一次出现的位置
if (firstTimeIndex == lastTimeIndex) { // 3. 若 首次等于最后 则就找到啦
return nums[i] // 4. 找到返回之即可
}
}
};
This method is slightly better, but I think the best way is to use the Map collection, which has high efficiency, good execution time and memory consumption ^_^
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。