• 请实现一个函数,输入一个整数数组和一个目标值,在数组中找到两个数使得它们的和等于目标值。


    今日份AI出笔试题:

    AI Golang笔试中级题目icon-default.png?t=N7T8https://bs.rongapi.cn/1702565828114780160/23

    完整题目:

    请实现一个函数,输入一个整数数组和一个目标值,在数组中找到两个数使得它们的和等于目标值。函数应该返回这两个数的索引,其中索引1必须小于索引2。可以假设每个输入只对应一种答案,而且同样的元素不会被重复利用。例如,给定数组 [2, 7, 11, 15] 和目标值 9,因为 nums[0] + nums[1] = 2 + 7 = 9,返回 [0, 1]。

    思路:

    这个题目拿到手之后,第一直觉是直接双循环,循环拿到第一个数,在剩余的里面去查找第二个数,查到了就提交。

    那作为中级题目,我们还是要稍微做一下优化的。

    我的优化思路是既然做了循环,有没有可能在过程中做一些缓存数据,加速之后的查找?

    开始想要不要直接做个排序,后来觉得排序本身也要计算量,而且这道题不需要完整排序,应该是要比排序快的。

    顺着这个思路,我想每次既然比较了一个数值,那我可以在这个过程中把原始数据按大小分成两个部分?

    这样外层循环一次,我就能得到粒度更细的一个分组,下次比较,太小的和太大的值都可以直接忽略,再把命中的数组分成两个就好了,比如上面这个例子,如果第二次查找2,那我只需要比较5以下的第一个分组,第二个分组直接跳过

    提交结果在最开始的链接里,但是提交之后,AI觉得问题如下:

    答案评价:代码逻辑基本正确,但是存在一些冗余的部分。对于分组的处理可以简化一些,并且可以使用map来存储已经遍历过的元素以提高查找效率。

    才想起来,直接用map就可以了……就是边循环,便把位置和值信息存到一个map里,之后如果map里有对应值,就拿出来直接返回,如果没有就再循环。

    不过我的方案对于需要返回多个可能值的情况还是有帮助的,把修正后的方案贴出来大家指正:

    1. type Group struct {
    2. Seperator *int
    3. Values [][2]int
    4. }
    5. func seperateGroup(seperator int, group *Group) (loc int, smallerGroup *Group, biggerGroup *Group, matched bool) {
    6. smallerGroup, biggerGroup = &Group{
    7. Seperator: &seperator,
    8. }, &Group{
    9. Seperator: group.Seperator,
    10. }
    11. for j := 0; j < len(group.Values); j++ {
    12. if group.Values[j][0] == seperator {
    13. return j, nil, nil, true
    14. } else if group.Values[j][0] < seperator {
    15. smallerGroup.Values = append(smallerGroup.Values, group.Values[j])
    16. } else {
    17. biggerGroup.Values = append(biggerGroup.Values, group.Values[j])
    18. }
    19. }
    20. return 0, smallerGroup, biggerGroup, false
    21. }
    22. func recurse(loc int, arr []int, target int, groups ...*Group) []int {
    23. if loc == len(arr)-1 {
    24. return nil
    25. }
    26. var cur = arr[loc]
    27. var remain = target - cur
    28. var newGroups []*Group
    29. i := 0
    30. for ; i < len(groups); i++ {
    31. if groups[i].Seperator == nil || remain <= *groups[i].Seperator {
    32. remainLoc, smallerGroup, biggerGroup, matched := seperateGroup(remain, groups[i])
    33. if matched {
    34. return []int{loc, groups[i].Values[remainLoc][1]}
    35. }
    36. if i == 0 {
    37. newGroups = []*Group{smallerGroup, biggerGroup}
    38. } else {
    39. newGroups = append(groups[:i-1], smallerGroup, biggerGroup)
    40. }
    41. break
    42. }
    43. }
    44. if i < len(groups)-1 {
    45. newGroups = append(newGroups, groups[i+1:]...)
    46. }
    47. return recurse(loc+1, arr, target, newGroups...)
    48. }
    49. // 主函数入口
    50. func FindMatchGroup(arr []int, target int) []int {
    51. if len(arr) < 2 {
    52. return nil
    53. }
    54. var remain = &Group{}
    55. for i := 1; i < len(arr); i++ {
    56. remain.Values = append(remain.Values, [2]int{arr[i], i})
    57. }
    58. return recurse(0, arr, target, remain)
    59. }

  • 相关阅读:
    MemGPT: Towards LLMs as Operating Systems
    Jmeter之JSON提取器说明示例
    安装linux子系统以及配置环境
    手把手教你用Python操纵Word自动编写离职报告
    windows 下使用virtualbox7.0设置共享文件夹详细,绝对好用
    JAVA:集合框架常见的面试题和答案
    android Studio为项目生成签名
    C语言 指针进阶 贰
    微机原理实验:字符转换为ASCII码
    Vue CLI 3 - 创建我们的项目
  • 原文地址:https://blog.csdn.net/baijiafan/article/details/133174054