一. 环形链表II
题目链接:力扣
思路:双指针法,快指针一次移动两个位置,慢指针一次移动一个位置,两指针必定在环内相交。
快指针一次移动两个位置,慢指针一次移动一个位置,那么它们相对位置一次只变化一个位置,因此必然会相遇。
因此,若两个指针在移动途中相遇,证明该链表有环。
而且,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
因此在相遇之后,在相遇位置出发一个节点,在头结点出发一个节点,同时移动,每次移动一个位置,返回相遇节点即可。
代码:
public class Solution {
public ListNode detectCycle(ListNode head) {
//新建快慢双指针
ListNode fastIndex = head;
ListNode slowIndex = head;
//快指针一次俩,慢指针一次一
while(fastIndex != null && fastIndex.next != null) {
fastIndex = fastIndex.next.next;
slowIndex = slowIndex.next;
//如果有环
if(fastIndex == slowIndex) {
//在相交位置新建一个指针
ListNode index1 = fastIndex;
//在头结点位置新建一个指针
ListNode index2 = head;
while(index1 != index2) {
//一次移动一个位置
index1 = index1.next;
index2 = index2.next;
}
//再次相遇,返回下标
return index1;
}
}
//未相遇,返回null
return null;
}
}
链表部分结束噜——
开始哈希表
二. 有效的字母异位词
代码链接:力扣
思路:数组就是简单的哈希表,因此可以通过新建一个长度为26的数组来存储值。
a到z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。
再遍历 字符串s的时候,只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,这样就将字符串s中字符出现的次数统计出来了。
而且不需要记住它的ASCII值,只需要 - ‘a’,求出相对差值。
代码:
class Solution {
public boolean isAnagram(String s, String t) {
//新建一个数组,存放元素
int[] recode = new int[26];
//遍历字符串s
for(int i = 0; i<s.length(); i++) {
//不需要记住,-a求出相对值即可
recode[s.charAt(i) - 'a']++;
}
//遍历字符串t
for(int i = 0; i<t.length(); i++) {
recode[t.charAt(i) - 'a']--;
}
for(int count : recode) {
//若该值不为0,说明s和t值一定不等
if(count != 0) {
return false;
}
}
return true;
}
}
三. 赎金信
题目链接:力扣
思路:和上一题几乎完全一样,只是最后的判断条件出了问题。
代码:
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
//特值判断
if(ransomNote.length() > magazine.length()) {
return false;
}
//定义映射数组
int[] recode = new int[26];
//分别遍历
for(char c : magazine.toCharArray()) {
recode[c - 'a'] += 1;
}
for(char c : ransomNote.toCharArray()) {
recode[c - 'a'] -= 1;
}
//若i<0,返回错
for(int i : recode) {
if(i < 0) {
return false;
}
}
return true;
}
}