Java&C++ 题解与拓展——leetcode667. 优美的排列 II【++ 在 java 和 C++ 中的差异】
题目要求
思路:规律构造
本质上是数学推导,分别找到 k k 最小( k=1 1 )和最大( k=n-1 )的排列方式,然后分段构造即可。按升序(or 降序)排列,相邻项的差值均为 1 1 ,此时 k=1 1 ;按一大一小穿插排列,即奇数位升序偶数位降序(or 反过来)排列,如 [1,n,2,n-1,\dots] [ 1 , n , 2 , n − 1 , … ] ,此时 k=n-1 。
那么只要让序列一半升序一半穿插即可实现;先构造出所有差值,即 [1,k+1,2,k,\dots] [ 1 , k + 1 , 2 , k , … ] ;然后将剩余的数升序排列 [n-k,n-k+1,\dots,n] [ n − k , n − 1 , … , n ] ;二者直接拼合即可,交界处的差值必定在前半段出现过,所以对答案没有影响。
Java
【是谁忘了判断越界错了半天,首先排除我自己】
时间复杂度: O(n) O ( n )
空间复杂度: O(1) O ( 1 ) ,忽略返回值
C++
发现了有趣的事,
++i
在 java 和 C++中的运行顺序是不同的,++ ++去查了一下发现其实
i++
也会有同样的问题,参考链接:C++在运行时,变量和值都在内存中一起存取计算,所以“一荣俱荣”;java 运行时存在 堆栈 ,等式前半段(赋值目标中的 i i )会先压入堆栈,然后进行计算再赋值。
时间复杂度: O(n) O ( n )
空间复杂度: O(1) O ( 1 ) ,忽略返回值
Rust
时间复杂度: O(n) O ( n )
空间复杂度: O(1) O ( 1 ) ,忽略返回值
总结
刚开始没仔细看题,以为是随机给 n n 个数构造,头都大了两圈,看到示例还想这咋净举这么简单的例子,脑子里走马灯了半天发现原来今儿:eyes:没上班。
这个构造思路属于是猛然一下迸发灵感,然后发现和题解一样,贼快乐~
还发现了没好好学语言运行原理而搞出来的溢出小问题,进而学习了自增在不同语言中的运行原理。
欢迎指正与讨论!
评论