一、题目要求:环形链表
题解:
代码
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode p1 = head;
ListNode p2 = head;
if(head == null || head.next == null){
return false;
}
while(p1 != null && p1.next != null){
p1 = p1.next.next;
p2 = p2.next;
if(p1 == p2)
return true;
}
return false;
}
}
思路: 使用快慢双指针法,当快指针p1 != null && p1.next != null
时,该链表没有尾节点,快指针走两步,慢指针走一步。当快指针与慢指针相遇时,说明此链表是环形的。若p1
为空了两指针还未相遇,则说明不是环形链表。
关键点:
- 快指针不能走到空,到空说明不是环形;
- 快指针一定能够追上慢指针
二、题目要求:数组移动零
题解
代码:
class Solution {
public void moveZeroes(int[] nums) {
int n = nums.length;
int index = 0; // 用来标记前面未转换的下标位置
for(int i = 0; i < n; i++){
if(nums[i] != 0){
nums[index++] = nums[i];
}
}
while(index < n) nums[index++]=0;
}
}
思路: 定义一个指针index
,指向下标为0的数组值,首先将所有不为0的值按顺序往前移。移动方法:遍历数组,当元素值不为0时,对该数组进行重新排序。每一个不为0的值插入数组时,执行index++
往后移一位。最后,将数组剩下的下标全部补0即可。
关键点:
- 要将不为0的值重新按序插入回数组中,当数组循环到最后一个下标时,此时的index就是最后一个不为0的元素
- 将剩余的下标全部补齐0,因为
index已经标记了最后一个不为0的下标
。所以插入0时,只需要从index查到数组长度即可。
三、题目要求:存在重复元素
题解
代码:
class Solution {
public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
for(int i = 1; i< nums.length ; i++){
if(nums[i] == nums[i-1]) return true;
}
return false;
//暴露破解——超时
// for(int i=0;i<nums.length;i++){
// for(int j=1+i;j<nums.length;j++){
// if(nums[i]==nums[j]){
// return true;
// }
// }
// }
// return false;
}
}
思路: 最容易想到的就是暴力解法,即将数组循环两遍逐个进行比较。但此方法无法通过一个测试点。因此使用数组自带的排序方法Arrays.sort()
将数组排序,这样就只需要对数组相邻两个元素值进行比较即可了。
总结:
通过这些天对于简单程度的链表和数组的算法题练习,我发现对于单指针、双指针和递归在这类题是比较适用的方法。因为数组和链表都有一个共同点,就是能通过上一节点(上一个下标)找到下一节点(下一下标),所以在此处使用这些方法还是比较好用的。