leetcode刷题记录
  • Leetcode刷题记录
  • 191 - 227 基本计算器2
  • 48 - 第二高的薪水
  • 226 - 494 目标和
  • 76 - 各位相加
  • 56 - 第十行
  • 196 - 328 奇偶链表
  • 106 - 485最大连续1的个数
  • 168 - 240 搜索二维矩阵2 - 001
  • 55 - 有效电话号码
  • 2 TOW SUM Ⅱ
  • 149 - 213 打家劫舍2
  • 91 - 有效的完全平方数
  • 59 - 198 打家劫舍
  • 166 - 92 反转链表2
  • 110 - 581 最短无序连续子数组
  • 197 - 454 四数相加2
  • 75 - 二叉树的所有路径
  • 41 - 最小栈
  • 27 - 最小差值
  • 177 - 337 打家劫舍3
  • 228 - 994 腐烂的橘子
  • 71 - 用栈实现队列
  • 30 - 将有序数组转换为二叉搜索树
  • 143 - 89 格雷编码
  • 184 - 152 乘积最大子序列
  • 221 - 354 俄罗斯套娃信封问题
  • 124 - 2 两数相加
  • 205 - 287 寻找重复数
  • 83 - 猜数字游戏
  • 25 - 对称二叉树
  • 90 - 两个数组的交集2
  • 163 - 877 石子游戏
  • 123 - 617 合并二叉树
  • 227 - 377 组合总和 Ⅳ
  • 144 - 146 LRU缓存机制
  • 18 - 加一
  • 145 - 215 数组中第k个最大元素
  • 65 - 存在重复元素
  • 17 - 最后一个单词的长度
  • 69 - 2的幂
  • 133 - 47 全排列2
  • 161 - 322 零钱兑换
  • 200 - 297 二叉树的序列化和反序列化
  • 152 - 63 不同路径2
  • 210 - 279 完全平方数
  • 154 - 264 丑数2
  • 183 - 212 单词搜索2
  • 22 - 删除排序链表中的重复元素
  • 100 - 左叶子之和
  • 128 - 16 最接近的三数之和
  • 204 - 162 寻找峰值
  • 190 - 239 滑动窗口最大值
  • 79 - 第一个错误版本
  • 178 - 52 n皇后2
  • 131 - 415 字符串相加
  • 8-最长公共前缀
  • 5-整数反转Reverse Integer
  • 159 - 120 三角形最小路径和
  • 64 - 反转链表
  • 21 - 爬楼梯
  • 36 - 买卖股票的最佳时机
  • 188 - 378 有序矩阵中第k小的元素
  • 135 - 54 螺旋矩阵
  • 24 - 相同的树
  • 33 - 路径总和
  • 202 - 179 最大数
  • 142 - 40 组合总和2
  • 104 - 414第三大的数
  • 180 - 140 单词拆分2
  • 129 - 33 搜索旋转排序数组
  • 225 - 474 一和零
  • 84 - 区域和检索- 数组不可变
  • 74 - 有效的字母异位词
  • 86 - 4的幂
  • 34 - 杨辉三角
  • 138 - 62 不同路径
  • 98 - 第n个数字
  • 85 - 3的幂
  • 49 - 超过经理收入的员工
  • 116 - 1025 除数博弈
  • 31 - 平衡二叉树
  • 97 - 判断子序列
  • 73 - 删除列表中的节点
  • 3-Two Sum IV - Input is a BST
  • 15 - 报数
  • 89 - 两个数组的交集
  • 167 - 74 搜索二维矩阵 - 001
  • 187 - 295 数据流的中位数
  • 164 - 72 编辑距离
  • 194 - 150 逆波兰表达式求值
  • 115 - 665 非递减数列
  • 81 - 单词规律
  • 139 - 78 子集
  • 150 - 148 排序链表
  • 140 - 90 子集2
  • 136 - 59 螺旋矩阵2
  • 16 - 最大子序和
  • 19 - 二进制求和
  • 12 - 移除元素
  • 112 - 628 三个数的最大乘积
  • 51 - 从不订购的客户
  • 39 - 只出现一次的数字
  • 189 - 347 前k个高频元素
  • 181 - 208 实现前缀树Trie
  • 35 - 杨辉三角2
  • 209 - 128 最长连续序列
  • 217 - 134 加油站
  • 147 - 230 二叉树搜索树中第k小的元素
  • 207 - 395 至少有K个重复字符的最长子串
  • git自动提交脚本
  • 212 - 127 单词接龙
  • 214 - 207 课程表
  • 117 - 661 图片平滑器
  • 186 - 334 递增的三元子序列
  • 105 - 448找到数组中消失的数字
  • 43 - excel表列名称
  • 113 - 643 子数组最大平均数1
  • 63 - 同构字符串
  • 7-罗马数字转整数
  • 195 - 138 复制带随机指针的链表
  • 107 - 532数组中的k-diff数对
  • 58 - 上升的温度
  • 141 - 39 组合总和
  • 182 - 79 单词搜索
  • 101 - 数字转换为16进制数
  • 125 - 5 最长回文子串
  • 23 - 合并两个有序数组
  • 40 - 环形链表
  • 95 - 字符串中的第一个唯一字符
  • 114 - 746使用最小花费爬楼梯
  • 37 - 买卖股票的最佳时机2
  • 132 - 46 全排列
  • 29 - 二叉树的层次遍历2
  • 77 - 丑数
  • 66 - 存在重复元素2
  • 68 - 翻转二叉树
  • 137 - 61 旋转链表
  • 60 - 快乐数
  • 54 - 位1的个数
  • 93 - 猜数字大小
  • 11 - 删除排序数组中的重复项
  • 134 - 51 N皇后
  • 99 - 二进制手表
  • 215 - 210 课程表 II
  • 224 - 518 零钱兑换 II
  • 127 - 11 盛最多水的容器
  • leetcode笔记
  • 4-3sum
  • 50 - 查找重复的电子邮箱
  • 176 - 621 任务调度器
  • 103 - fizz buzz
  • 220 - 188 买卖股票的最佳时机 IV
  • 82 - Nim游戏
  • 213 - 200 岛屿数量
  • 72 - 二叉树的最近公共祖先
  • 87 - 反转字符串
  • 78 - 缺失数字
  • 118 - 437 路径综合3
  • 121 - 538 把二叉树转换为累加树
  • 20 - x的平方根
  • 126 - 8 字符串转换整数
  • 157 - 464 我能赢吗
  • 158 - 42 接雨水
  • 80 - 移动零
  • 122 - 543 二叉树的直径
  • 199 - 380 常数时间插入、删除和获取随机元素
  • 背包九讲
  • 9-有效的括号
  • 47 - 组合两个表
  • 1 两数之和(Two Sum)
  • 62 - 计数质数
  • 88 - 反转字符串中的元音字母
  • 14 - 搜索插入位置
  • 28 - 二叉树层次遍历1
  • 119 - 461 汉明距离
  • 70 - 回文链表
  • 32 - 二叉树的最小深度
  • 46 - 阶乘后的零
  • 120 - 557 反转字符串中的单词3
  • 170 - 154 寻找旋转排序数组中的最小值2 - 006
  • 57 - 删除重复的电子邮箱
  • 53 - 颠倒二进制位
  • 223 - 132 分割回文串
  • 146 - 238 除自身外数组的乘积
  • 109 - 566重塑矩阵
  • 45 - excel表序列号
  • 174 - 1004 最大连续1的个数3
  • 171 - 替换空格 - 002
  • 179 - 131 分割回文串
  • 198 - 18 四数之和
  • 6-回文数
  • 52 - 旋转数组
  • 172 - 151 翻转字符串里面的单词 - 044
  • 192 - 224 基本计算器
  • 173 - 567 字符串的排列 027
  • 208 - 124 二叉树中的最大路径和
  • 13 - 实现strStr()
  • 42 - 相交链表
  • 169 - 153 寻找旋转排序数组最小值 - 006
  • 108 - 561数组拆分
  • 211 - 329 矩阵中的最长递增路径
  • 153 - 64 最小路径和
  • 225 - 416 分割等和子集
  • 222 - 486 预测赢家
  • 203 - 324 摆动排序2
  • 175 - 260 只出现一次的数字3 - 040
  • 155 - 96 不同的二叉搜索树
  • 165 - 887 鸡蛋掉落
  • 102 - 最长回文串
  • 193 - 341 扁平化嵌套列表迭代器
  • 10 - 合并两个有序链表
  • 162 - 300 最长上升子序列
  • 160 - 139 单词拆分
  • 151 - 236 二叉树的最近公共祖先
  • 44 - 求众数
  • 185 - 384 打乱数组
  • 216 - 149 直线上最多的点数
  • 61 - 移除链表元素
  • 218 - 91 解码方法
  • 67 - 用队列实现栈
  • 219 - 123 买卖股票的最佳时机
  • 比赛
  • 92 - 两整数之和
  • 130 - 43 字符串相乘
  • 96 - 找不同
  • 111 - 605种花问题
  • 201 - 218 天际线问题
  • 26 - 二叉树的最大深度
  • 206 - 315 计算右侧小于当前元素的个数
  • 94 - 赎金信
  • 38 - 验证回文串
  • 148 - 142 环形链表2
  • 156 - 95 不同的二叉搜索树2
Powered by GitBook
On this page
  • 题目
  • 解答
  • 排序
  • 与其用map,不如用更快的桶排序
  • 直接相减ascii
  • 异或
  • 测试代码
  • go
  • python

Was this helpful?

96 - 找不同

题目

给定两个字符串 s 和 t,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。

示例:

输入: s = "abcd" t = "abcde"

输出: e

解释: 'e' 是那个被添加的字母。

解答

感觉可以变成数组,然后一个个找index。不过这样有重复的就不行了。。

然后就想到,可以先排序,再一个个比对。

不过需要先判断下长短才行

排序

const getWrongOne = function (longer, shorter) {
  for (let i = 0; i < longer.length; i++) {
    if (longer[i] !== shorter[i]) {
      return longer[i];
    }
  }
}
var findTheDifference = function (s, t) {
  let sArr = s.split('').sort()
  let tArr = t.split('').sort()
  if (sArr.length > tArr.length) {
    return getWrongOne(sArr, tArr)
  } else {
    return getWrongOne(tArr, sArr)
  }
};

Runtime: 80 ms, faster than 10.49% of JavaScript online submissions for Find the Difference.

Memory Usage: 35.2 MB, less than 100.00% of JavaScript online submissions for Find the Difference.

起码是做出来了😂😂

go的string是切片,却似乎无法直接排序

s := "bcd"
sort.Slice(s, func(i, j int) bool {
  return s[i] < s[j]
})

直接这样的话会报错

goroutine 1 [running]: reflect.Swapper(0x10a5800, 0xc00009c030, 0x11754c0) /usr/local/Cellar/go/1.12.7/libexec/src/reflect/swapper.go:16 +0x730 sort.Slice(0x10a5800, 0xc00009c030, 0xc000084f50) /usr/local/Cellar/go/1.12.7/libexec/src/sort/slice.go:19 +0xb2 main.main() /Users/joey/Study/leetcode/test/code.go:57 +0x93 exit status 2

所以只能先转成slice

func getDiff(longer, shorter []rune) byte {
    for i := 0; i < len(shorter); i++ {
        if longer[i] != shorter[i] {
            return byte(longer[i])
        }
    }
    return byte(longer[len(longer)-1])
}
func findTheDifference(s string, t string) byte {
    sArr := []rune(s)
    sort.Slice(sArr, func(i, j int) bool {
        return sArr[i] < sArr[j]
    })
    tArr := []rune(t)
    sort.Slice(tArr, func(i, j int) bool {
        return tArr[i] < tArr[j]
    })
    if len(sArr) > len(tArr) {
        return getDiff(sArr, tArr)
    } else {
        return getDiff(tArr, sArr)
    }
}

Runtime: 4 ms, faster than 19.81% of Go online submissions for Find the Difference.

Memory Usage: 2.5 MB, less than 100.00% of Go online submissions for Find the Difference.

在gitDiff()函数里面,报错过指针越界。结果是因为指向longer最后一位,shorter是没有的。。

这点在js就不用考虑,因为没有,就是空,那自然啥都直接返回否

可能这就是为啥,刷题记录都是python之类的弱类型语言吧。。很多事情都不用考虑,主体思想有了就能直接写

用go刷题,没有高并发场景,感觉很吃亏啊

与其用map,不如用更快的桶排序

var findTheDifference = function (s, t) {
  let data = new Array(26)
  for (let i = 0; i < 26; i++) {
    data[i] = 0
  }
  for (const item of s) {
    data[item.charCodeAt() - 97]++
  }
  for (const item of t) {
    data[item.charCodeAt() - 97]--
  }
  for (let i = 0; i < data.length; i++) {
    if (data[i] !== 0) {
      return String.fromCharCode(i + 97);
    }
  }
};

Runtime: 64 ms, faster than 53.33% of JavaScript online submissions for Find the Difference.

Memory Usage: 35.6 MB, less than 100.00% of JavaScript online submissions for Find the Difference.

疯狂for循环,感觉很蠢哈哈😂

go对应的排序就不能这么写了。。因为如果一开始定义的data变成了0,再-1就会报error

这就让我想到,完全可以一次遍历么。。

func findTheDifference(s string, t string) byte {
    var data [26]int
    for _, value := range s {
        data[value-97]++
    }
    for _, value := range t {
        if data[value-97] == 0 {
            return byte(value)
        } else {
            data[value-97]--
        }
    }
    return t[len(t)-1]
}

Runtime: 0 ms, faster than 100.00% of Go online submissions for Find the Difference.

Memory Usage: 2.2 MB, less than 100.00% of Go online submissions for Find the Difference.

js也可以

var findTheDifference = function (s, t) {
  let data = []
  for (let i = 0; i < 26; i++) {
    data[i] = 0
  }
  for (const item of s) {
    data[item.charCodeAt() - 97]++
  }
  for (const item of t) {
    if (data[item.charCodeAt() - 97] === 0) {
      return item
    } else {
      data[item.charCodeAt() - 97]--
    }
  }
  return t[t.length - 1]
};

Runtime: 68 ms, faster than 33.79% of JavaScript online submissions for Find the Difference.

Memory Usage: 35.4 MB, less than 100.00% of JavaScript online submissions for Find the Difference.

写这个的时候遇到了一个坑,当我想偷懒少打几个字,把data[item.charCodeAt()-9]令为了一个elem

在下面else的时候,不能执行elem—。或者说执行了之后data并未改变。go和js都不行

...
for (const item of t) {
  const elem = data[item.charCodeAt() - 97]
  if (elem === 0) {
    return item
  } else {
    elem--
  }
}
...

可能是因为,这是把其中的值拿出来赋值给了elem,即使是改了elem,也不会影响到原来的data。。

python可以直接比较出现的次数,都不用建数组

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        for i in t:
            if t.count(i) - s.count(i) != 0:
                return i

Runtime: 40 ms, faster than 74.95% of Python3 online submissions for Find the Difference.

Memory Usage: 14 MB, less than 10.00% of Python3 online submissions for Find the Difference.

直接相减ascii

作者:QQqun902025048

俩ascii加起来,再相减,差的那个就是想要的数

这操作。。服气吼

var findTheDifference = function (s, t) {
  let count = 0
  for (const item of s) {
    count += item.charCodeAt() - 97
  }
  for (const item of t) {
    count -= item.charCodeAt() - 97
  }
  return String.fromCharCode(Math.abs(count) + 97)
};

Runtime: 52 ms, faster than 96.21% of JavaScript online submissions for Find the Difference.

Memory Usage: 35.7 MB, less than 100.00% of JavaScript online submissions for Find the Difference.

我是怕它溢出,强行减一个97😂😂

func findDiff(longer, shorter string) byte {
    var count int32
    for _, value := range longer {
        count += value - 97
    }
    for _, value := range shorter {
        count -= value - 97
    }
    if count < 0 {
        count = -count
    }
    return byte(count + 97)
}
func findTheDifference(s string, t string) byte {
    if len(s) > len(t) {
        return findDiff(s, t)
    } else {
        return findDiff(t, s)
    }
}

Runtime: 0 ms, faster than 100.00% of Go online submissions for Find the Difference.

Memory Usage: 2.2 MB, less than 100.00% of Go online submissions for Find the Difference.

为了避开变成0之后的panic。。只能这么做。

一开始是count==0之后直接return,但有可能中间变成0的。。

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        return chr(sum(map(ord, t)) - sum(map(ord, s)))

Runtime: 36 ms, faster than 91.95% of Python3 online submissions for Find the Difference.

Memory Usage: 13.7 MB, less than 10.00% of Python3 online submissions for Find the Difference.

异或

感觉找不同,异或都是一个思路,毕竟相同的就会变成0

func findDiff(longer, shorter string) byte {
    ans := longer[len(longer)-1]
    for i := 0; i < len(shorter); i++ {
        ans ^= longer[i]
        ans ^= shorter[i]
    }
    return ans
}
func findTheDifference(s string, t string) byte {
    if len(s) > len(t) {
        return findDiff(s, t)
    }
    return findDiff(t, s)
}

Runtime: 0 ms, faster than 100.00% of Go online submissions for Find the Difference.

Memory Usage: 2.2 MB, less than 100.00% of Go online submissions for Find the Difference.

js好像做不了。。

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        n = 0
        for i in s:
            n ^= ord(i)
        for i in t:
            n ^= ord(i)

        return chr(n)

Runtime: 36 ms, faster than 91.95% of Python3 online submissions for Find the Difference.

Memory Usage: 13.7 MB, less than 10.00% of Python3 online submissions for Find the Difference.

测试代码

go

go怎么取字符串的byte呢?

因为是切片所以可以直接后面加[0]取😂

func Multi(t *testing.T) {
    var DATA = []struct {
        a        string
        b        string
        expected byte
    }{
        {"acde", "caebd", "b"[0]},
        {"abcd", "abcde", "e"[0]},
        {"aa", "a", "a"[0]},
    }

    for i, elem := range DATA {
        ans := findTheDifference(elem.a, elem.b)
        if ans != elem.expected {
            t.Error("😶 wrong:", i+1)
            t.Errorf("* target: %v", elem.expected)
            t.Error("* ans:", &ans)
            return
        }
    }
}

func TestFunc(t *testing.T) {
    // Single(t)
    Multi(t)
}

python

想在以后刷题中加入python,于是查了单元测试怎么写

import unittest2 as unittest


# ================ code ===================
class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        for i in t:
            if t.count(i) - s.count(i) != 0:
                return i


# ========================================
TEST_DATA = [
    {
        "input": ["abcd", "abcde"],
        "target": "e"
    },
    {
        "input": ["acbd", "acebd"],
        "target": "e"
    }
]


class Test(unittest.TestCase):
    @unittest.skipIf(not isinstance(TEST_DATA[0]["input"], list), "skip")
    def test_multi(self):
        for t in TEST_DATA:
            self.assertEqual(Solution.findTheDifference(self, *t["input"]), t["target"])

    @unittest.skipIf(isinstance(TEST_DATA[0]["input"], list), "skip")
    def test_single(self):
        for t in TEST_DATA:
            self.assertEqual(Solution.findTheDifference(self, t["input"]), t["target"])


if __name__ == '__main__':
    unittest.main()

我更喜欢用json把所有数据存起来😂

话说这个skip的装饰器,有点酷吼。只要输入是放在list里面的,就不会测试它

于是找了一下go的跳过

package main

import (
    "testing"
)

// ==== prepare =======
...

func a(input string) int {
    return 1
}

// ======= test ============
func Single(t *testing.T) {
    var DATA = []struct {
        input    string
        expected int
    }{
        {"leetcode", 0},
        {"loveleetcode", 2},
        {"aa", -1},
    }

    for i, elem := range DATA {
        ans := a(elem.input)
        if ans != elem.expected {
            t.Error("😶 wrong:", i+1)
            t.Errorf("* target: %v", elem.expected)
            t.Error("* ans:", ans)
            return
        }
    }
}

func Multi(t *testing.T) {
    var DATA = []struct {
        a        string
        b        string
        expected byte
    }{
        {"acde", "caebd", "b"[0]},
        {"abcd", "abcde", "e"[0]},
        {"aa", "a", "a"[0]},
    }

    for i, elem := range DATA {
        ans := findTheDifference(elem.a, elem.b)
        if ans != elem.expected {
            t.Error("😶 wrong:", i+1)
            t.Errorf("* target: %v", elem.expected)
            t.Error("* ans:", &ans)
            return
        }
    }
}

func TestMulti(t *testing.T) {
    Multi(t)
}

func TestSingle(t *testing.T) {
    t.SkipNow()
    Single(t)
}

关键是v嗯额skipnow()函数,配上go的简单输出模式,很舒服。

Previous130 - 43 字符串相乘Next111 - 605种花问题

Last updated 5 years ago

Was this helpful?

作者:YarkAwk 链接:

链接:

作者:QQqun902025048 链接:

作者:guanpengchn 链接:

https://leetcode-cn.com/problems/find-the-difference/solution/pythonbi-jiao-mei-ge-zi-fu-zai-liang-ge-zi-fu-ch-2/
https://leetcode-cn.com/problems/find-the-difference/solution/python-1-xing-ascii-he-zhi-chai-by-qqqun902025048/
https://leetcode-cn.com/problems/find-the-difference/solution/python-1-xing-ascii-he-zhi-chai-by-qqqun902025048/
https://leetcode-cn.com/problems/find-the-difference/solution/hua-jie-suan-fa-389-zhao-bu-tong-by-guanpengchn/