48Days-Day03 | 删除公共字符,两个链表的第一个公共结点,mari和shiny

删除公共字符

删除公共字符_牛客题霸_牛客网

算法思路

直接哈希,把第二个字符塞集合里面,遍历第一个,只要在集合里面有的就跳过

代码

import java.util.HashSet;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String strA = scan.nextLine();
        String strB = scan.nextLine();
        HashSet set = new HashSet<>();
        for (int i = 0; i < strB.length(); i++) {
            if (strB.charAt(i) != ' ') set.add(strB.charAt(i));
        }

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < strA.length(); i++) {
            if (set.contains(strA.charAt(i))) continue;
            sb.append(strA.charAt(i));
        }

        System.out.println(sb);
    }
}

两个链表的第一个公共节点

两个链表的第一个公共结点_牛客题霸_牛客网

算法思路

此处我们采用快慢指针法,具体讲述请参考我的博客

面试题思路

代码

import java.util.*;
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if (pHead1 == null || pHead2 == null) return null;
        int size1 = 0, size2 = 0;
        ListNode cur1 = pHead1, cur2 = pHead2;
        ListNode fast, slow;
        while (cur1.next != null) {
            size1++;
            cur1 = cur1.next;
        }

        while (cur2.next != null) {
            size2++;
            cur2 = cur2.next;
        }

        int n = Math.abs(size1 - size2);
        if (size1 > size2) {
            fast = pHead1;
            slow = pHead2;
        } else {
            fast = pHead2;
            slow = pHead1;
        }

        while (n > 0) {
            fast = fast.next;
            n--;
        }

        while (fast != null) {
            if (fast == slow) return fast;
            fast = fast.next;
            slow = slow.next;
        }
        return null;
    }
}

Mari和Shiny

mari和shiny

算法思路

此处我们采用的是dp

  1. 我们引入三个状态转移方程s[i], h[i], y[i],分别表示区间[0, i]中有多少个s, sh, shy
  2. 对于s[i],有两种情况,i位置为s时,s[i] = s[i-1] + 1;而不为s时,就应该和前面[0, i-1]区间中的s的数量相同,所以s[i] = s[i-1]
  3. 同理,对于h[i]同样有两种情况,i位置为h时,h[i]实际上由两部分构成,[0, i-1]区间中的s的数量和sh的数量,所以h[i] = s[i-1] + h[i-1],不为h时则和[0, i-1]区间中sh数量相同
  4. 同理,对于y[i]来说,为y时,y[i] = h[i-1] + y[i-1];不为y时,y[i] = y[i-1]

注意点

存储结果的长度应该为long,否则会溢出

代码【动态转移方程版】

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        String str = scan.next();
        long[] s = new long[n];
        long[] h = new long[n];
        long[] y = new long[n];
        s[0] = str.charAt(0) == 's' ? 1 : 0;
        for (int i = 1; i < n; i++) {
            if (str.charAt(i) == 's') s[i] = s[i - 1] + 1;
            else s[i] = s[i - 1];

            if (str.charAt(i) == 'h') h[i] = s[i - 1] + h[i - 1];
            else h[i] = h[i - 1];

            if (str.charAt(i) == 'y') y[i] = h[i - 1] + y[i - 1];
            else y[i] = y[i - 1];
        }
        System.out.println(y[n - 1]);
    }
}

代码【空间优化版】

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        String str = scan.next();
        long s = 0, h = 0, y = 0;
         for (int i = 0; i < n; i++) {
             if (str.charAt(i) == 's') s += 1;
             else if (str.charAt(i) == 'h') h += s;
             else if (str.charAt(i) == 'y') y += h;
         }
        System.out.println(y);
    }
}

 

你可能感兴趣的:(笔试训练48Days,链表,java,算法)