剑指offer(Java版)面试题36——46

面试题36:第一个只出现一次的字符位置

在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置

代码:(借助哈希)
        import java.util.LinkedHashMap;
        public class Solution {
            public int FirstNotRepeatingChar(String str) {
                LinkedHashMap  map = new LinkedHashMap();
                for(int i=0;i

面试题37:数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:

题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5

示例1
输入

1,2,3,4,5,6,7,0

输出

7

代码1:(牛客超时)
            public int InversePairs(int [] array) {
                    if(array == null) return 0;
                    int count=0;
                    for(int i=0;iarray[j]) count++;
                        }
                    }
                    int r = count%1000000007;
                    return r;
                }

代码2:

面试题38:两个链表的第一个公共结点

输入两个链表,找出它们的第一个公共结点。

代码:
        import java.util.Stack;
        public class Solution {
            public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
             if(pHead1==null || pHead2==null) return null;
                 //借助栈或者哈希都可以
                 Stack s1 = new Stack();
                 Stack s2 = new Stack();
                 ListNode p1 = pHead1;
                 ListNode p2 = pHead2;
                 while(p1 != null || p2 != null) {
                     if(p1 != null) {
                         s1.push(p1);
                         p1 = p1.next;
                     }
                     if(p2 != null) {
                         s2.push(p2);
                         p2 = p2.next;
                    } 
                 }
                 p1=null;
                 while(!s1.isEmpty() && !s2.isEmpty()) {
                     if(s1.peek() == s2.peek()){
                        p1 = s1.peek();
                         s1.pop();
                         s2.pop(); 
                     }else{
                         break;
                     }
                 }
                 return p1;
            }
        }

面试题39:数字在排序数组中出现的次数

统计一个数字在排序数组中出现的次数。

代码1:简单的从前到后的遍历
        public class Solution {
            public int GetNumberOfK(int [] array , int k) {
               if(array==null) return 0;
                int count=0;
                int flag=0;
                for(int i=0;i

面试题40:二叉树的深度

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

代码:
        public class Solution {
            public int TreeDepth(TreeNode root) {
                if(root ==null) return 0;
                int num=0;
                num = digui(root,num);//当时调试的时候是这里出的问题
                return num;
            }
            public int digui(TreeNode root,int num) {
                if(root==null) return num;
                num = num+1;
                int num1 = digui(root.left,num);//注意num的值传递
                int num2 = digui(root.right,num);
                num = num1>num2? num1:num2;
                return num;
            }
        }

注意:这道题错的位置在加注释的地方,这道题本身不难,但是关于递归的思想和java函数的值传递的本质要有更深刻的认识!!!

面试题41:平衡二叉树

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

代码:
        public class Solution {
            public boolean IsBalanced_Solution(TreeNode root) {
                if(root==null) return true;
                return getDepth(root)!=-1;
            }
            public int getDepth(TreeNode root) {
                if(root==null) return 0;
                int left = getDepth(root.left);
                if(left==-1) return -1;
                int right = getDepth(root.right);
                if(right==-1) return -1;
                if(left-right>=-1 && left-right<=1) {
                    return 1+Math.max(left, right) ;             
                }else {
                    return -1;      
                }
            }
        }

知识点:
1. 平衡二叉树:如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树

面试题42:数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

代码1:HashMap
            //num1,num2分别为长度为1的数组。传出参数
            //将num1[0],num2[0]设置为返回结果
            import java.util.LinkedHashMap;
            import java.util.Set;
            public class Solution {
                public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
                    if(array==null) return;
                    LinkedHashMap h = new LinkedHashMap<>();
                    for(int i=0;i s = h.keySet();
                    int j=0;
                    for(int i:s) {
                        num[j++]=i;
                    }
                    num1[0]=num[0];
                    num2[0]=num[1];
                }
            }

代码2:异或

面试题43:和为S的连续正数序列

>
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:

输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序.

代码:
            import java.util.ArrayList;
            public class Solution {
                public ArrayList > FindContinuousSequence(int sum) {
                    ArrayList > a = new ArrayList >(); 
                    if(sum<=2) return a;
                    int small=1,big=2;

                    int temp = big+small;
                    while(small<=sum/2) {
                        while(temp t = new ArrayList();
                            for(int i=small;i<=big;i++) {
                                t.add(i);
                            }
                            a.add(t);
                        }
                        temp-=small;
                        small+=1;
                    }
                    return a;
                }
            }

面试题44:和为S的两个数字

>
输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。(也就是最先找到的)
输出描述:

对应每个测试案例,输出两个数,小的先输出。

代码:
        import java.util.ArrayList;
        public class Solution {
            public ArrayList FindNumbersWithSum(int [] array,int sum) {
                ArrayList a = new ArrayList();
                if (array == null || array.length < 2) {
                    return a;
                }
                int i=0,j=array.length-1;
                while(isum){
                        j--;
                    }else{
                        i++;
                    }

                }
                return a;
            }
        }

注意:使用的是夹逼准则

面试题45:左旋转字符串

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

代码:
        public class Solution {
            public String LeftRotateString(String str,int n) {
                if(str==null || str.length()==0) return str;
                if(n<=0) return str;
                int length = str.length();
                String s,s1,s2;
                if(nlength) {
                    int num = n%length;
                    s1 = str.substring(0, num);
                    s2 = str.substring(num);
                    s = s2.concat(s1);
                }else {
                    s = str;
                }
                return s;
            }
        }

面试题46:翻转单词顺序列

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

代码1:(未通过)但是我感觉方法是可以的
            public class Question46 {
                 public String ReverseSentence(String str) {
                     if(str==null || str.length()==0) return str;
                     String [] a;
                     int num=0;//计算空格的个数
                     for(int i=0;i

注意:关于字符串和字符数组之间的转化有很多捷径,所以不需要一直自己循环!

你可能感兴趣的:(Java)