算法训练营(第一期)第二天(java)
学习感悟:1,我在生活当中应当尽量让成长成为一种刚需.首先,因为我自身在学习的时候有一种急于求成坏毛病.其次,我在看富兰克林自传的时候,意识到其一生都在不断寻求个人成长.我们可以选着过这样的人生.
题目
一、链表相交(leetcode)
题目
双层循环解决问题
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode cur1=headA;
ListNode cur2=headB;
while(cur1!=null){
//此处一开始忘记每次遍历后返回链表头部
cur2=headB;
while(cur2!=null){
if(cur1==cur2) return cur1;
cur2=cur2.next;
}
cur1=cur1.next;
}
return null;
}
}
更好的解决办法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//我在找公共节点时发现,短的链表限制了公共节点出现的位置.故而我可以将长链表的前面的一些节点跳过.
ListNode cura=headA;
ListNode curb=headB;
int lengtha=0;
int lengthb=0;
while(cura!=null){
cura=cura.next;
lengtha++;
}
while(curb!=null){
curb=curb.next;
lengthb++;
}
//此时我们若是判断那个长之后在遍历有些麻烦,所以我可以交换让lengtha变为最长
if(lengthb>lengtha){
int temp = lengtha;
lengtha=lengthb;
lengthb=temp;
ListNode temp1=headA;
headA=headB;
headB=temp1;
}
int k=lengtha-lengthb;
cura=headA;
curb=headB;
while(k>0){
k--;
cura=cura.next;
}
while(cura!=null){
if(cura==curb){return cura;}
cura=cura.next;
curb=curb.next;
}
return null;
}
}
二、环形链表二(leetcode142)
题目
我错误解法:
尝试通过双层循环判定那两个节点的下个节点指向相同的空间但不太好实现.
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
//链表有环的话必然会导致有两个节点的next指针相同,而且其中一个节点必为尾部节点.但是有环的话我怎么知道那个是尾部呢?所以这个思路不太能行得通
ListNode cur=head;
ListNode cur1=head;
while(cur!=null){
cur1=head;
while(cur1!=null){
cur1=cur1.next;
}
cur=cur.next;
}
}
}
正确解法:
对于正确的解法需要进行一定的数学推导
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast=head;
ListNode slow=head;
//交点位置
ListNode index;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
fast=head;
index=slow;
//之后双方一步一步走直道相遇就是x
while(fast!=index){
fast=fast.next;
index=index.next;
}
return fast;
}
}
return null;
}
}
三、有效的字母异位词
题目
错误解法:
想要通过元素出现的次数来判断,当只在s中出现时为奇数.但是我忽略了在s中出现两次
class Solution {
public boolean isAnagram(String s, String t) {
int[] a=new int[256];
for (int i=0;i<s.length();i++){
a[(int) s.charAt(i)]++;
}
for (int i=0;i<t.length();i++){
a[(int) t.charAt(i)]++;
}
for (int i : a) {
if (i%2!=0) return false;
}
return true;
}
}
正确解法:
当在t中出现时减掉,如果不为零则说明不一样
class Solution {
public boolean isAnagram(String s, String t) {
int[] a=new int[256];
for (int i=0;i<s.length();i++){
a[(int) s.charAt(i)]++;
}
for (int i=0;i<t.length();i++){
a[(int) t.charAt(i)]--;
}
for (int i : a) {
if (i!=0) return false;
}
return true;
}
}