每日一练2.21

1. 题目描述:输入几组对应的字符串,其中一个是English,另一个是外语,
 开始是输入字典,然后根据外语来查询字典,没有时输出eh

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.StringTokenizer;

/**
 * 题目描述:输入几组对应的字符串,其中一个是English,另一个是外语,
 * 开始是输入字典,然后根据外语来查询字典,没有时输出eh
 * 例子: dog  ogday
 *       cat  atcay
 *       pig  igpay
 *       froot ootfray
 *       loops oopslay
 *
 *
 *       atcay
 *       ittenkay
 *       oopslay
 *       output输出
 *       cat
 *       eh
 *       loops
 */

/**
 *       字符串tokenizer类允许应用程序将字符串拆分成令牌,可以在创建时或每个令牌的基础上指定一组分隔符(分隔标记的字符
 *       以下是使用tokenizer的一个示例。 代码:
 *
 *      StringTokenizer st = new StringTokenizer("this is a test");
 *      while (st.hasMoreTokens()) {
 *          System.out.println(st.nextToken());
 *      }
 *  打印以下输出:
 *
 *      this
 *      is
 *      a
 *      test
 *   */

/**
 *      以下示例说明了如何使用String.split方法将字符串分解为其基本令牌:
 *
 *      String[] result = "this is a test".split("\\s");
 *      for (int x=0; x<result.length; x++)
 *          System.out.println(result[x]);
 *  打印以下输出:
 *
 *      this
 *      is
 *      a
 *      test
 */
public class HashQuestion {
    public static void main(String[] args) throws IOException {
        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
        Hashtable<String ,String > table = new Hashtable<>();
        String s="";
        StringTokenizer tokenizer;
        while (true){
            s=stdin.readLine();
            if (s.trim().equals("*")){ break;}
            tokenizer=new StringTokenizer(s);
            s=tokenizer.nextToken();
            table.put(tokenizer.nextToken(),s);
        }
        System.out.println("output");

        while (true){
            s=stdin.readLine();
            if (s.trim().equals("*")){ break;}
            if (table.get(s)!=null){
                System.out.println(table.get(s));}
            else {
                System.out.println("eh");}
        }
    }
}

 

2.题目描述:找出数组中逆序对的数量


import java.util.Arrays;
public class MergeSort {
    private static int ORDER_COUNT=0;
    public static void main(String []args) throws InterruptedException {
        int []arr = {9,8,7,6,5,4,3,2,1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println(ORDER_COUNT);
        int [] arr2={1,2,3,4,5,6,7,0};
      

        ORDER_COUNT=0;
        sort(arr2);
        System.out.println(Arrays.toString(arr2));
        System.out.println(ORDER_COUNT);
    }
    public static void sort(int []arr){

        int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
        mergeSort(arr,0,arr.length-1,temp);
    }
    private static void  mergeSort(int[] arr,int left,int right,int []temp){
        if(left<right){
            int mid = (left+right)/2;
            mergeSort(arr,left,mid,temp);//左边归并排序,使得左子序列有序
            mergeSort(arr,mid+1,right,temp);//右边归并排序,使得右子序列有序
            merge(arr,left,mid,right,temp);//将两个有序子数组合并操作
        }
    }
    private static void merge(int[] arr,int left,int mid,int right,int[] temp){
        int i = left;//左序列指针
        int j = mid+1;//右序列指针
        int t = 0;//临时数组指针
        //求解归逆序对中的数量只需要改进一下while循环方法
        while (i<=mid && j<=right){
            if(arr[i]<=arr[j]){  //此时没有逆序对
                temp[t++] = arr[i++];
            }else {  //否则产生了逆序对,我们需要对逆序对做出统计
                temp[t++] = arr[j++];
                ORDER_COUNT=ORDER_COUNT%1000000007;
                ORDER_COUNT+=mid-i+1;//+1的作用是将0的序列变为按下标的序列,
                // mid+1是左边的总数,i是第一个比右边数值大的坐标
            }
        }
        while(i<=mid){//将左边剩余元素填充进temp中
            temp[t++] = arr[i++];
        }
        while(j<=right){//将右序列剩余元素填充进temp中
            temp[t++] = arr[j++];
        }
        t = 0;
        //将temp中的元素全部拷贝到原数组中
        while(left <= right){
            arr[left++] = temp[t++];
        }
    }
}

3.题目描述:构建一个二叉搜索树

public class TreeQuestion {
    public static class TreeNode {
        private String species;
        private TreeNode left;
        private TreeNode right;
        private int count;
    }

    public static class Tree {
        private int total;
        private TreeNode root = new TreeNode();

        public void insert(String newSpecies, TreeNode root) {
            if (root.count == 0) {
                root.species = newSpecies;
                root.count++;
                total++;
                return;
            } else {
                if (root.species.compareTo(newSpecies) > 0) {
                    if (root.left == null) {
                        root.left = new TreeNode();
                    }
                    insert(newSpecies, root.left);
                } else {
                    if (root.species.compareTo(newSpecies) < 0) {
                        if (root.right == null) {
                            root.right = new TreeNode();
                        }
                        insert(newSpecies, root.right);
                    } else {
                        root.count++;
                        total++;
                    }
                }
            }
        }


        public void travlTree(TreeNode root) {
            if (root == null) {
                return;
            }
            travlTree(root.left);
            System.out.println(root.species + " ");
            double p = root.count * 100 / total;
            System.out.printf("%.4f", p);
            System.out.println();
            travlTree(root.right);
        }
    }
}

 

4.两个链表数求和

//题目描述:两个链表数求和
public class AddTwoNumbers {
    //input (2->4->3)+(5->6->4)
    //output(7->0->8)
/**
 * 给定两个链表,然后按顺序把链表相加 从左到右
 * 1:2-4-3   5-6-4
 * ans: 8- 0 - 7
 */

    public static void main(String[] args) {
        ListNode l1=new ListNode(2);
        ListNode l2=new ListNode(4);
        ListNode l3=new ListNode(3);
       l1.next=l2;
       l2.next=l3;


        ListNode p1=new ListNode(5);
        ListNode p2=new ListNode(6);
        ListNode p3=new ListNode(4);
        p1.next=p2;
        p2.next=p3;


        ListNode ans = addTwoNumbers(l1,p1);
        while (ans!=null){
            System.out.println(ans.val);
            ans=ans.next;
        }
    }

    public static ListNode addTwoNumbers (ListNode l1,ListNode l2) {
        ListNode dummy = new ListNode(0);
        int sum = 0;
        ListNode cur = dummy;
        ListNode p1=l1,p2=l2;

        while (p1!=null||p2!=null){
            if (p1!=null){
                sum+=p1.val;
                p1=p1.next;
            }
            if (p2!=null){
                sum+=p2.val;
                p2=p2.next;
            }
            cur.next = new ListNode(sum%10);  //取余
            sum/=10;   //进位
            cur=cur.next;   //移位
        }
        if (sum==1){  //把最后一个进位连起来
            cur.next = new ListNode(1);
        }
        return dummy.next;

    }
}
 class ListNode
{
    int val;
    ListNode next;

    public ListNode(int x){
        val=x;
    }

}

5.题目描述:给定一个数组,找出数组中是否有两个数的和为target的值,不可以使用相同的元素两次

public class demo1 {
    public static int[] twoSum(int[] nums,int target){
        if (nums.length<2||nums==null){
            return new int[]{-1,-1,};
        }
        int[] ans = new int[]{-1,-1};
        //以数组的值为map的键,以数组索引为map的值
        HashMap<Integer,Integer> map=new HashMap<Integer, Integer>();
        for (int i = 0; i <nums.length ; i++) {
            if (map.containsKey(target-nums[i])){
                ans[0]=map.get(target-nums[i]);
                ans[1]=i;
                break;
            }
            map.put(nums[i],i);
        }
        return ans;
    }
    public static void main(String[] args) {
        int[] ints=new int[]{0,1,2,3,4,5,6,7,8};
        int[] p=  twoSum(ints,9);
        System.out.println(p[0]+" "+p[1]);
    }
}

6.题目描述: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

import java.util.HashMap;
import java.util.HashSet;

/**
 * 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
 *
 * 示例 1:
 *
 * 输入: "abcabcbb"
 * 输出: 3
 * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
 * 示例 2:
 *
 * 输入: "bbbbb"
 * 输出: 1
 * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
 * 示例 3:
 *
 * 输入: "pwwkew"
 * 输出: 3
 * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
 *      请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
 *
 *      a b c a b c b b 一开始i是从0,1,2,3,4,5 遍历走下去
 *      j 一开始为0   ,之后走的是扫描后第一个不重复的元素开始 举例 j=0, j=3 j=4
 *
 *
 *
 */
public class demo03 {

    public int lengthOfLongestSubstring(String s) {
        if (s==null||s.length()==0) return 0;
        HashMap<Character,Integer> map = new HashMap<Character, Integer>();
        int res=0;
        //i代表遍历走到哪里就是哪里,j代表我们不重复的起点在哪里
        for (int i = 0,j=0; i <s.length() ; i++) {
            if (map.containsKey(s.charAt(i))){
                j=Math.max(j,map.get(s.charAt(i))+1);
            }
            map.put(s.charAt(i),i);
            res =Math.max(res,i-j+1);
        }
        return res;
    }
    public int lengthOfLongestSubstring2(String s) {
        if (s==null||s.length()==0) return 0;
        HashSet<Character> set=new HashSet<Character>();
        int res=0;
        //i代表遍历走到哪里就是哪里,j代表我们不重复的起点在哪里
        for (int i = 0,j=0; i <s.length() ; i++) {
            if (set.contains(s.charAt(i))){
                set.remove(s.charAt(j++));// j始终代表的是不重复的起点,如果找到重复元素就从左侧开始逐步删除
            }else {
                set.add(s.charAt(i));
                res = Math.max(res,set.size());
            }
        }
        return res;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值