算法intuition之-给定一个整形数组,找出其中两个数之和为指定数

http://www.fengchang.cc/post/55

 

这题本没什么难度,然而看到某书上说:

 

这种证明是不对的,因为完全没有考虑错过的情况,是不严谨或者胡乱做假设前提的论证方式,故出一篇勘误。

 

intuition1: 在无序的情况下,必须两两比较才能确定最终结果,那么结果必然是O(n2)的时间复杂,这个不好。

intuition2:在有序的情况下,可以用两个指针初始化为头和尾,即为i和j,那么n[i]+n[j]可以得出一个值,这个值跟给定值M有三种情况

1, M==n[i]+n[j]

2, M>n[i]+n[j]

3, M<n[i]+n[j]

第一种情况就不用说了,直接得到答案,

第二种情况,意味着两者之和太小了,那么需要增大,增大的直觉方法有两种,要么向右移动i,要么向右移动j。假设最终的一个结果是m,n(也就是i移动m位,j移到n位)那么我们设定一个原则,凡是第二种情况出现时,就向右移动i, 凡是第三种情况出现时,就想左移动j,那么按照这种原则是否会出现m,n被错过的情况?也就是说例如出现i先越过了m,但j还在n的后面,或者另一种情况,j先越过了n,然而j还在m左边的情况?可以证明,不可能!

证明如下:从m,n在i,j之间的状态说起,假设i先达到了m(另一种情况是j先达到了n,根据对称性,这两者没有本质区别,但至少会发生两者中的一种),那么此时j尚未达到n,则必然出现第三种情况,那么根据我们的移动原则,j就必然想左移动,并且,只要没有达到n,这个动作会一直持续直到达到n,从而不会错过n,根据对称性,另一种情况同样如此,所以根据以上设定的移动规则,必然不会错过可能出现的 答案。

 

还有一种空间换时间的方式,用hashmap来记录值和index,这样只要遍历一遍,并用Hashmap直接判定是否存在另一个下标。

但是这种方法有一个问题,就是当存在相同值时,并且恰好求和的两个数是同值不同位时,必然会出问题。修正方式是hashmap中的value用list或者set来存储,那么如果最终两个值对应的index set不同,或者index set相同但set size>1,那么就是存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的MBTI性格测试的代码示例,使用Go语言编写: ```go package main import ( "bufio" "fmt" "os" "strings" ) func main() { questions := []string{ "I prefer to spend time alone rather than socializing with a large group.", "I rely on my intuition more than on my senses.", "I like to plan things in advance rather than being spontaneous.", "I prefer to have a few close friends rather than many acquaintances.", "I prefer to work alone rather than in a team.", "I value logic and reason more than emotions and feelings.", "I like to have a routine rather than being flexible.", "I prefer to focus on the big picture rather than the details.", "I tend to be more reserved and quiet than outgoing and talkative.", "I like to keep my options open rather than making a decision quickly.", } answers := make([]string, len(questions)) reader := bufio.NewReader(os.Stdin) for i, q := range questions { fmt.Printf("(%d) %s\n", i+1, q) answer, _ := reader.ReadString('\n') answer = strings.TrimSpace(answer) answers[i] = answer } aCount := 0 tCount := 0 for _, a := range answers { switch a { case "A", "a": aCount++ case "T", "t": tCount++ default: fmt.Println("Invalid answer: ", a) } } var mbtiType string if aCount > tCount { mbtiType = "Introverted" } else { mbtiType = "Extroverted" } if answers[0] == "A" || answers[0] == "a" { mbtiType += " Intuitive" } else { mbtiType += " Sensing" } if answers[2] == "A" || answers[2] == "a" { mbtiType += " Judging" } else { mbtiType += " Perceiving" } fmt.Printf("Your MBTI type is %s\n", mbtiType) } ``` 该代码定义了一个问题数组和答案数组,通过循环询问问题并记录答案。然后,对答案数组进行计,根据计结果确定MBTI类型(根据A和T的量)。最后,根据前三个答案,确定MBTI类型的第二个和第三个字母。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值