今天看一下这几道题目
//环形链表
//思路: 快慢指针,定义两个指针,慢指针指向头结点,快指针指向头结点下一个结点,
//每次慢指针一次走一步,快指针一次走两步,如果快指针和慢指针可以相遇则说明链表存在环
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) {
return false;
}
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
//环形链表II
//思路: 这道题是找到入环的第一个结点,先使用快慢指针判断是否存在环,
//不存在则结束,否则就将快指针重新指向头结点,慢指针不变,接着快慢指针每次都只走一步,
//直到再次相遇的结点就是该链表的入环结点
//注意这里快慢指针一开始需要都指向头结点,不能像上面那种方法那样指向不同位置,因为
//这里需要计算入环结点位置,尝试了一下上面那种指向不同位置的方式进行判环然后找入环结点发现
//会进入死循环
public ListNode getCycleNode(ListNode head) {
if (head == null || head.next == null) {
return null;
}
ListNode slow = head;
ListNode fast = head;
do {
if (slow != null) {
slow = slow.next;
}
if (fast != null && fast.next != null) {
fast = fast.next.next;
}
if (slow == fast) {
fast = head;
while (slow != fast) {
if (slow != null) {
slow = slow.next;
}
if (fast != null) {
fast = fast.next;
}
}
return fast;
}
} while (slow != fast);
return null;
}
//找到所有数组中消失的数字
//思路: 由题意知,nums数组是在[1, n]的,可以利用哈希表计算元素索引的方式 (num - 1) % lenght,
//该方式可以保证nums的每个元素num被分配到num- 1的坐标位置上,为了不打乱数组元素原本位置,我们可以
//用加n的方式标记当前位置已经被标记
public List<Integer> findDisappearedNumbers(int[] nums) {
int n = nums.length;
for (int num : nums) {
int index = (num - 1) % n;
nums[index] += n;
}
List<Integer> ret = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (nums[i] <= n) {
ret.add(i + 1);
}
}
return ret;
}