Java关于for循环优化的问题
今天刷了leetcode的每日一题,题是比较简单,但是中间遇到了一个超时的问题,最终分析是因为在for循环内创建了一个数组,把数组放到for循环外边就可以通过。
题目:565. 数组嵌套
我最初的解法是:
public int arrayNesting(int[] nums) {
int maxRes = 0;
int length = nums.length;
for (int i = 0; i < length; i++){
int res = 0;
boolean[] arr = new boolean[length];
while (!arr[i]){
arr[i] = true;
res++;
i = nums[i];
}
maxRes = Math.max(maxRes, res);
}
return maxRes;
}
我创建一个新的数组用于标记指定位置有没有走到过,并且将数组放在了for循环内,最终导致提交的时候报【超出时间限制】,后面看了别人的题解发现也有这种解题思路的,差别就是他们的数组是在for循环外面的!!!
- 思考1:后面想了一下为什么我要放在for循环内?因为我想的是每次遍历的时候要把这个数组清空,但其实对题目再进行思考就会发现每一个点都只有一个入度和一个出度,所以不需要担心不重置数组影响后面的判断,可以把创建数组放在外面;继续想,既然每一个点都只有一个入度和一个出度,他们是一个完整的环,那么在原数组上操作也是可以的!这也是另一种解题方法原地标记法。还有,这个题只要求给出最大集合的大小,那么我们只要判断出我们已经求出的
maxRes >= nums.length/2
就可以停止循环,所以最终提交的代码为:
public int arrayNesting(int[] nums) {
int maxRes = 0;
int length = nums.length;
for (int i = 0; i < length; i++){
if(maxRes * 2 >= length){
break;
}
int res = 0;
while (nums[i] < length){
int num = nums[i];
nums[i] = length;
res++;
i = num;
}
maxRes = Math.max(maxRes, res);
}
return maxRes;
}
- 思考2:最初提交没通过是因为在for循环中创建数组导致超时,由此想到之前跟朋友聊过的一个问题:两个嵌套的for循环,要想让效率更高,外层循环遍历的应该是大数还是小数? 又去查了一下这个问题,发现有人总结的比较好:java关于for循环的效率优化