剑指offer

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

逐个字符进行判断,e或E、小数点或符号最多出现一次,而e或E的前一个必须是数字,且不能是第一个或最后一个字符,符号的前一个字符不能是e或E。
分析:
一个字符串是数值的要求:

1)每个字符串都必须是 0–9,e,E,+, - , .(小数点)的格式

2)+ -,e,E,.不能在末尾

3)小数点只能出现一次

4)正负号在中间时,前面是e,E,后面是数字

5)e或者E的后面是+ -的时候,后面不能有小数点

在这里插入图片描述

public boolean isNumeric(char[] str) {
		 String ss = String.valueOf(str);
//		 先判断每个字符是否合法
		 int len = ss.length();
		 for(int i=0; i<len; i++){
			 char c = ss.charAt(i);
			 if(!((c>='0' && c <= '9') || c=='e' || c=='E' || c=='+' || c=='-'|| c=='.')){
				 return false;
			 }
		 }//
//		 正负号,E不能在末尾
		 if(ss.charAt(len-1) == '+' || ss.charAt(len-1) == '-' || ss.charAt(len-1) == 'E' || ss.charAt(len-1) == 'e'){
			 return false;
		 }
//		 判断小数点,只能有一个
		 if(ss.indexOf(".") != ss.lastIndexOf(".")){
			 return false;
		 }
//		 正负号在中间的位置时,前面的是e,E,后面是数字
		 for(int i=1; i<len-1; i++){
			 char c = ss.charAt(i);
			 if(c == '+' || c=='-'){
				 if(!(ss.charAt(i-1) == 'e' || ss.charAt(i-1) == 'E') ||
						 !(ss.charAt(i+1)>='0' && ss.charAt(i+1)<='9')){
					 return false;
				 }
			 }
		 }//
//		e的后面不能有小数点12E+4.3
		 for(int i=1; i<len; i++){
			 char c = ss.charAt(i);
			 if(c == 'e' || c=='E'){
//				`在这里插入代码片` if(i==len-1) return false;
				 if(ss.charAt(i+1) == '+' || ss.charAt(i+1) == '-'){
//					 从i+2开始往后没有小数点.则返回-1
					 if(ss.indexOf(".", i+2) != -1){
						 return false;
					 }
				 }
			 }
		 }//
		 return true;
	 }
public class Solution {
    public boolean isNumeric(char[] str) {
        
       //首先 Ee  只能出现一次 不能再最后一位 出现后面
       //是数字 ,点 只能出现一次 
        // +- 出现 第一次第二次只能 在Ee 后面才可以。
       int len = str.length;
        boolean sign = false, dot = false, hasE = false;
        for (int i = 0; i < len; i++){
            if (str[i] == 'e' || str[i] == 'E'){
                if (i == len -1)
                    return false; //e后面一定要接数字
                if (hasE == true)  //不能同时存在连个e
                    return false;
                hasE = true;
            }else if (str[i] == '+' || str[i] == '-'){
                if (sign && str[i - 1] != 'e' && str[i - 1] != 'E')
                    return false;  //第二次出现的+或-一定要在e后面
                if (!sign && i > 0 && str[i - 1] != 'e' && str[i - 1] != 'E')
                    return false;  //第一次出现的也一定要在e后面
                sign = true;
 
            }else if (str[i] == '.') {
                if (hasE || dot)  //.只能出现一次,e后面也不能接小数点
                    return false;
                dot = true;
            }else {
                if (str[i] < '0' || str[i] > '9')
                    return false;
            }
 
        }
        return true;
    }
}

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

解题思路
既然是获取第一个不重复的字符,首先我们需要知道字符是否重复,这个需要根据字符的输入动态的统计,很直观想到的数据结构就是HashMap。其次在输出的时候需要保证是第一个,因而还需要记录字符输入的顺序,这里用到的数据结构比较多,动态数组ArrayList比较适合。

import java.util.*;
public class Solution {
    //Insert one char from stringstream
    HashMap<Character,Integer> map = new HashMap();
    ArrayList <Character>list = new ArrayList<Character>();
    public void Insert(char ch)
    {
        if(map.containsKey(ch)){
            map.put(ch,map.get(ch)+1);
        }else{
            map.put(ch,1);
        }
        list.add(ch);
        
    }
  //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    { 
       char c ='#';
        for(char key : list){
            if(map.get(key)==1){
                c=key;
                break;
            }
        }
    return c;
    }
}

题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

在这里插入图片描述

/*
public class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode node)
    {
        if(node== null) return null;
        //如果有右子树 那就是右子树的最左边节点因为中序遍历 是  左中右
        
        if(node.right!=null){
            node = node.right;
            while(node.left!=null){
                node=node.left;
        }return node;
        
        
    }
        //如果没有就找 节点的父节点的父节点。直到当前节点得父节点是节点得找到的
        //左孩子才可以
        while(node.next!=null){
            if(node.next.left==node)return node.next;
            node=node.next;
        }
        return null;
    }
}

题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的

  • DFS使用stack来保存成对的节点
  • 1.出栈的时候也是成对成对的 ,
    1.若都为空,继续;
    2.一个为空,返回false;
    3.不为空,比较当前值,值不等,返回false;
  • 2.确定入栈顺序,每次入栈都是成对成对的,如left.left, right.right ;left.rigth,right.left
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

import java.util.*;
public class Solution {
    boolean isSymmetrical(TreeNode pRoot)
    {
          if(pRoot == null) return true;
        Stack<TreeNode> s = new Stack<>();
        s.push(pRoot.left);
        s.push(pRoot.right);
        while(!s.empty()) {
            TreeNode right = s.pop();//成对取出
            TreeNode left = s.pop();
            if(left == null && right == null) continue;
            if(left == null || right == null) return false;
            if(left.val != right.val) return false;
            //成对插入
            s.push(left.left);
            s.push(right.right);
            s.push(left.right);
            s.push(right.left);
            
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值