相似的代码,相同的功能,无法找出它们之间的任何区别

时间:2019-06-13 02:59:18

标签: algorithm

https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/discuss/93007/simple-java-in-place-sort-solution

能否请您检查上面的链接?

我听不懂代码

  

while(nums [i]!= i + 1 && nums [i]!= nums [nums [i]-1])

这两者之间有什么区别?

1) nums[i] != i+1
2) nums[i] != nums[nums[i]-1]

例如

index 0 : 1
index 1 : 2
index 2 : 3

然后,第一个只需使用index就可以检查 index+1是值。

和第二个

nums[0] = nums[nums[i]-1]
nums[0] = nums[nums[0]-1]
nums[0] = nums[1-1]
nums[0] = nums[0]

最终也是同一件事,只是为了证明 索引值=索引+1。

但是为什么while循环必须同时具有两个条件? 或者我们可以只使用其中之一?

2 个答案:

答案 0 :(得分:3)

我同意第二个条件是不必要的。实际上,我认为它不必要地使代码混乱。

用英语,代码本质上说“如果[something]和(x!= y),然后交换x和y”。所有“ x!= y”检查的作用是防止x与(本身相等)交换x。但这是禁止操作,因此可以在不更改行为或O(n)性能的情况下删除支票。

取消该检查将使算法更容易理解:“对于每个插槽i,虽然插槽i上的项目是错误的,请将其交换到它所属的位置。”

[更新]

哇!我刚刚意识到检查的重点...它防止了潜在的无限循环,在该循环中您不断来回交换相同的值。 (因为条件实际上是“ while”,而不是“ if”。)

所以所提出的算法是正确的。

答案 1 :(得分:1)

  
      
  1. nums [i]!= i + 1
  2.   

价值就是它的价值所在吗?如果不是,可以将其交换到其位置...

这是必需的,因为您必须测试每个位置

  
      
  1. nums [i]!= nums [nums [i] -1]
  2.   

是否需要将值交换到其位置?

这是必需的,因为算法将每个元素都放置在链中的位置。

以这个例子为例:

[3,1,2,4,6,5,8,7]

很明显,您需要重新排列1,2,3和5,6和7,8。

让我们看一下如何进行排序:

i:0 [3,1,2,4,6,5,8,7] 3<->2
i:0 [2,1,3,4,6,5,8,7] 2<->1
i:0 [1,2,3,4,6,5,8,7] now 1 is at its place, go to the right and find another chain
i:1 [1,2,3,4,6,5,8,7] 2 at its place
i:2 [1,2,3,4,6,5,8,7] 3 at its place
i:3 [1,2,3,4,6,5,8,7] 4 at its place
i:4 [1,2,3,4,6,5,8,7] 6<->5
i:4 [1,2,3,4,5,6,8,7] now is 5 at its place, go to the right and find another chain
i:5 [1,2,3,4,5,6,8,7] 6 at its place
i:6 [1,2,3,4,5,6,8,7] 8<->7
i:6 [1,2,3,4,5,6,7,8] now is 7 at its place, go to the right and find another chain
i:7 [1,2,3,4,5,6,7,8] 8 at its place
END

请注意,算法无法对链接中给出的数组进行排序!该算法提供的是,如果在初始数组元素e中存在,那么它将在其末尾处。在给定的示例中,两次出现3,一次放置在正确的位置,而另一次不在!但是算法的末尾保留了位于正确位置的值,而忽略了其他值。这就是“排序和重复项去除”算法或“最长严格增加序列算法”。