刷题找工作第10篇

剑指offer 第 49题

今日第一题:
把字符串转化为整数

题目描述
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
输入描述:
输入一个字符串,包括数字字母符号,可以为空
输出描述:
如果是合法的数值表达则返回该数字,否则返回0

public class Solution {
    public int StrToInt(String str) {
        if(str==null||str.length()==0) return 0;
        
        if(str.charAt(0)=='-')
        {
            boolean b = str.substring(1,str.length()).matches("[0-9]{1,}");
            if(!b) return 0;
            
            return convert(str.substring(1,str.length()),false);
            
            
        }else{
            String s=null;
            if(str.charAt(0)=='+')
            {
                s = str.substring(1,str.length());
            }else{
                s = str;
            }
            boolean b = s.matches("[0-9]{1,}");
            if(!b) return 0;
            return convert(s,true);
            
        }
    }
    
    private int convert(String str,boolean t)
    {
        int carry = 0;
        for(int i=0;i<str.length();++i)
        {
            carry*=10;
            carry += str.charAt(i)-'0';
            
        }
        if(!t) carry = -carry;
        return carry;
    }
}

数组中的重复数字
注意:数组内的数字 不会超过 n,因此可以不使用 hashMap 的方法

题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

public class Solution {
    // Parameters:
    //    numbers:     an array of integers
    //    length:      the length of array numbers
    //    duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
    //                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
    //    这里要特别注意~返回任意重复的一个,赋值duplication[0]
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    public boolean duplicate(int arr[],int length,int [] duplication) {
        boolean[] map = new boolean[length];
        for(int i=0;i<length;++i)
        {
            if(map[arr[i]]==true)
            {
                duplication[0] = arr[i];
                return true;
            }
            map[arr[i]] = true;
        }
        return false;
    }
}

构建乘积数组
题目描述
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。
看了半天终于看懂了
链接:https://www.nowcoder.com/questionTerminal/94a4d381a68b47b7a8bed86f2975db46?f=discussion
来源:牛客网

B[0] = A[1] * A[2] * A[3] * A[4] *…*A[n-1] ;(没有A[0])
B[1 ]= A[0] * A[2] * A[3] * A[4] *…*A[n-1] ;(没有A[1])
B[2] = A[0] * A[1] * A[3] * A[4] *…*A[n-1] ;(没有A[2])

链接:https://www.nowcoder.com/questionTerminal/94a4d381a68b47b7a8bed86f2975db46?f=discussion
来源:牛客网

借助两个数组lefts和rights,一个记录B[i]值的左乘结果A[0]A[1]…*A[i-1],一个记录B[i]值的右乘结果A[i+1]A[i+2]…*A[n-1],然后B[i]=lefts[i]*rights[i];

在这里插入图片描述

import java.util.ArrayList;
public class Solution {
    public int[] multiply(int[] A) {
        int[] ans = new int[A.length];
        ans[0] =1;
        //计算左边数组
        for(int i=1;i<ans.length;++i)
        {
            ans[i]=ans[i-1]*A[i-1];
        }
        
        //计算右边数组
        int carry = 1;
        for(int i=ans.length-2;i>=0;--i)
        {
            carry*=A[i+1];
            ans[i]*=carry;
        }
        
        
        return ans;
    }
}

这应该是最优解法了

第4题
表示数值的字符串
题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。

。。不想再看其他解法了,脑壳痛

public class Solution {
    public boolean isNumeric(char[] str) {
        
        try{
            double b = Double.parseDouble(new String(str));
        }catch(Exception e)
        {
            return false;
        }
        return true;
    }
}

第五题
字符流中第一个不重复的字符

题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。

import java.util.*;
public class Solution {
    
    private LinkedHashMap<Character,Integer> table = new LinkedHashMap();
    
    //Insert one char from stringstream
    public void Insert(char ch)
    {
         int i =  table.getOrDefault(ch,0);
         table.put(ch,i+1);
    }
  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
         Set<Map.Entry<Character,Integer>> set =  table.entrySet(); 
         for(Map.Entry<Character,Integer> p:set)
         {
             if(p.getValue()==1)
             {
                 return p.getKey();
             }
         }
        return '#';
    }
}

用 LinkeHashMap 保证有序

链表的环的入口节点
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null
思路一: 使用 一个 HashSet ,如果添加失败,说明set已经存在该节点了,返回节点

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
import java.util.*;
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead==null) return pHead;
        HashSet<ListNode> set = new HashSet();
        
        ListNode begin = pHead;
        while(begin!=null)
        {
            if(!set.add(begin))
            {
                return begin;
            }
            begin = begin.next;
        }
        return begin;
    }
}

思路二:

在这里插入图片描述

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
import java.util.*;
public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
         ListNode fast = pHead;
         ListNode slow = pHead;
        
        while(fast!=null&&fast.next!=null)
        {
            fast = fast.next.next;
            slow = slow.next;
            
            if(fast==slow) 
                break;       
        }
        if(fast==null||fast.next==null) return null;
        slow = pHead;
        while(fast!=slow)
        {
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
   
    }
}

删除链表中的重复节点

题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode deleteDuplication(ListNode pHead)
    {
        ListNode begin = new ListNode(-1);
        begin.next = pHead;
        ListNode end  = pHead;
        ListNode ans = begin;
        
        while(end!=null)
        {
            if(end.next!=null&&end.val==end.next.val)
            {
                while(end.next!=null&&end.val==end.next.val)
                {
                    end = end.next;

                }
                begin.next = end.next;
                end = end.next;//记得要把记录删除掉,这个节点没用了,从下一个节点开始
                
            }
            else{
                begin= begin.next;
                end = end.next;
            }
            
            
        }
        
        return ans.next;
        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值