删除数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
难易度:简单
解题思路
- 双指针
因为题目中的数组是有序数组,所以只要后一位和前一位不同,那么肯定后面不会有相同的数,那么就只需要把所有不重复的数,移动到数组前面就可以了。所以考虑使用双指针的方式,记录两个数字的位置,按位比较
var removeDuplicates = function (nums: number[]) {
let pre = 0 // 无重复数组的最后一个位置
let next = 1 // 下一个需要比较数字的指针
const len = nums.length
while(next < len){
if (nums[pre] == nums[next]){ // 遇到两个数重复了
next++ // 后移需要比较的指针
} else {
nums[pre + 1] = nums[next] // 当遇到不重复的数字时,将这个数前移
pre++
next++
}
}
return pre + 1
};
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
难易度:容易
解题思路:
- 利用indexof。indexof为内置函数,在内部是做了很多优化的,在任何时候自己写的函数,优化肯定是比不上内置函数的
var strStr = function(haystack: string, needle: string): number {
return haystack.indexOf(needle)
};
- 找到needle在 haystack 中的位置,那么 就默认haystack是更长的字符串,遍历haystack,找到needle第0个字符串的位置,再截取一个和needle等长的字符串,进行比较
var strStr = function(haystack: string, needle: string): number {
const nLen = needle.length
if (!nLen) return 0
const len = haystack.length
for(let i = 0; i < len; i++){
if (haystack[i] == needle[0]) {
if (haystack.substring(i, i + nLen) == needle) return i
}
}
return -1
};
两数相除
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分
例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
提示:
- 被除数和除数均为 32 位有符号整数。
- 除数不为 0。
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。
难易度:中等
解题思路:
- 既然不能用乘法和除法,那么就用减法嘛,除法可以理解为
被除数 减去n次 除数,n为除法的整数解,但是这题有几个坑
- 题中数字是32位有符号整数,但是
Math.abs(-2^31)是会越界的,所以把所有的数都变成负数去计算 - 特殊情况
-2^31 / -1是会越界的(别问我怎么知道的)
var divide = function (dividend: number, divisor: number) {
if (dividend <= -Math.pow(2, 31) && divisor == -1) return Math.pow(2, 31) -1 // 特殊情况
const flag = (dividend < 0 && divisor < 0) || (dividend >= 0 && divisor >= 0) // 用于结果是正还是负
dividend = -Math.abs(dividend)
divisor = -Math.abs(divisor)
let res = 0
while (dividend <= divisor) { // 循环相减
dividend = dividend - divisor
res++
}
return flag ? res : -res
};
- 位运算符
dividend每次减去2^n个divisor(尽可能多),同时res每次加2^n
var divide2 = function (dividend: number, divisor: number) {
if (dividend <= -Math.pow(2, 31) && divisor == -1) return Math.pow(2, 31) - 1
const flag = (dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0);
dividend = -Math.abs(dividend)
divisor = -Math.abs(divisor)
let res = 0
while (dividend <= divisor) {
let temp = divisor
let cal = 1
while (dividend - temp <= temp) {
temp = temp << 1
cal = cal << 1
}
dividend -= temp
res += cal
}
return flag ? res : -res
};
唉,这周公司项目太忙了,同时又在学习python深度学习,高数那段搞得我头昏脑涨的,都没刷几道题,我太难了!