剑指offer-java(3)

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

import java.util.*;
public class Solution{
    public ArrayList<ArrayList<Integer>> findContinuousSequence(int sum){
        ArrayList<ArrayList<Integer>> listsum=new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> list=new ArrayList<Integer>();
        if(sum<3)return listsum;
        int start=1;
        int end=2;
        int mid=(1+sum)/2;
        int tmp=start+end;
        list.add(start);
        list.add(end);
        while(start<mid){
            if(tmp==sum){
                listsum.add(new ArrayList<Integer>(list));
                end++;
                tmp+=end;
                list.add(end);
            }else if(tmp<sum){
                end++;
                tmp+=end;
                list.add(end);
            }else{
                tmp-=start;
                list.remove(new Integer(start));
                start++;
            }
        }
        return listsum;
    }
}

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

import java.util.*;
public class Solution{
        public ArrayList<Integer> FindNumbers(int[] array,int sum){
    ArrayList<ArrayList<Integer>> listsum=new ArrayList<ArrayList<Integer>>();
    for(int i=0;i<array.length;i++){
        ArrayList<Integer> list=new ArrayList<Integer>();
        for(int j=i+1;j<array.length;j++){
            if(array[i]+array[j]==sum){
                list.add(array[i]);
                list.add(array[j]);
                list.add(array[i]*array[j]);
            }
        }
        if(!list.isEmpty())
            listsum.add(new ArrayList<Integer>(list));
    }
    if(listsum.size()==0)
        return new ArrayList<Integer>();
    Collections.sort(listsum,new Comparator<ArrayList<Integer>>(){
        public int compare(ArrayList<Integer> o1,ArrayList<Integer> o2){
            return o1.get(2).compareTo(o2.get(2));  
        }
    });
    ArrayList<Integer> temp=listsum.get(0);
    ArrayList<Integer> lis=new ArrayList<Integer>();
    for(int i=0;i<temp.size()-1;i++){
        lis.add(temp.get(i));
    }
    return lis;
}
}

对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。

import java.util.*:
public class Solution{
    public String leftRotateString(String str, int n){
        if(str.length()==0)
            return str;
        StringBuffer sb1=new StringBuffer(str);
        StringBuffer sb2=new StringBuffer(str);
        StringBuffer sb=new StringBuffer();
        sb1.delete(0,n);
        sb2.delete(n,str.length());
        return sb.append(sb1.toString()).append(sb2.toString());
    }
}

“student. a am I”。顺序翻转了“I am a student.

import java.util.*;
public class Solution{
    public String ReverseString(String str){
        if(str==null||str.length()==0)
            return str;
        if(str.trim().equals("")){
            return str; 
        }
        String[] s=str.split(" ");
        StringBuffer sb=new StringBuffer();
        for(int i=s.length-1;i>=0;i--){
            sb.append(s[i]).append(" ");
        }
        return sb.toString().trim();
        //sb.toString().substring(0,sb.length()-1);
        //sb.substring(0,sb.length()-1);
    }
}

大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),

import java.util.*;
public class Solution{
    public boolean isContinuous(int[] numbers){
        if(numbers==null||numbers.length==0||numbers.length>5)
            return false;
        ArrayList<Integer> list=new ArrayList<Integer>();
        int len=numbers.length;
        int count=0;
        for(int i=0;i<len;i++){
            if(numbers[i]==0)
                count++;
            else
                list.add(numbers[i]);
        }
        Collections.sort(list);
        int len1=list.size();
        if(Math.abs(list.get(0)-list.get(len1-1))>4)
            return false;
        for(int i=0;i<len1-1;i++){
            int temp=list.get(i+1)-list.get(i);
            if(temp>0&&temp<5)
                continue;
            else
                return false;

        }
        return true;
    }
}

画圈中最后剩下的数
,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数….这样下去….直到剩下最后一个小朋友,

public class Solution{
    public int LastRemaining(int n,int m){
        if(n==0)
            return -1;
        int s=0;
        for(int i=2;i<=n;i++){
            s=(s+m)%i;
        }
        return s;
    }
}

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

//和为n(n+1)/2,除以2可以使用右移来表示
public class Solution{
    public int sum(int n){
        int sum=(int)(Math.pow(n,2)+n);
        return sum>>1;
    }
}

求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

import java.math.BigInteger;
public class Solution{
    public int Add(int num1,int num2){
        BigInteger b1=new BigInteger(String.valueOf(num1));
        BigInteger b2=new BigInteger(String.valueOf(num2));
        return b1.add(b2).intValue();
    }
}

字符串转换成一个整数,要求不能使用字符串转换整数的库函数。

public class Solution{
    public int StrToInt(String str){
//需考虑是否为空,有正负号等情况,鲁棒性。      if(str==null||str.length()==0)
            return 0;
        char[] a=str.toCharArray();
        int sum=0;
        int fuhao=0;
        if(a[0]=='-')
            fuhao=1;
        for(int i=fuhao;i<a.length;i++){
            if(a[i]=='+')
                continue;
            if(a[i]<'9'||a[i]>'0')
                return 0;
            sum=sum*10+a[i]-'0';

        }
        return fuhao==0?sum:sum*(-1);
    }
}

数组中重复的数字

public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers==null||length==0)
            return false;
        Arrays.sort(numbers);
        for(int i=0;i<length;i++){
            for(int j=i+1;j<length;j++){
                if(numbers[i]==numbers[j]){
                    duplication[0]=numbers[i];
                    return 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]。不能使用除法。

import java.util.*;
public class Solution{
    public int[] multiply(int[] A){
        int len=A.length;
        int[] b=new int[len];
        if(A.length==0)
            return b;
        int[] c=new int[len];
        int[] d=new int[len];

        c[0]=A[0];
        d[len-1]=A[len-1];
        for(int i=1;i<len;i++){
            c[i]=c[i-1]*A[i];
        }

        for(int i=len-2;i>=0;i--){
            d[i]=d[i+1]*A[i];
        }

        b[0]=d[1];
        b[len-1]=c[len-2];
        for(int i=1;i<len-1;i++){
            b[i]=c[i-1]*d[i+1];
        }
        return b;
    }
}

请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)

public class Solution{
    public boolean match(char[] str,char[] pattern){
        if(str==null&&pattern==null)
            return true;
        if(str==null||pattern==null)
            return false;
        return match(str,0,str.length,pattern,0,pattern.length);
    }
    private boolean match(char[] str,int i,int length,char[] pattern,int j, int length2){
        if(i==length&&j==length2)//主串和匹配串都匹配结束
            return true;
        if(i!=length && j==length2)//主串没有结束,匹配串结束
            return false;
        if(j+1<length2&&pattern[j+1]=='*'){
            if(i<length&&(str[i]==pattern[j]||pattern[j]=='.')){
        //主串和模式串当前字符匹配
                //主串向后移动,匹配串不变 aaa和a*
                    return match(str,i+1,length,pattern,j,length2)||
//主串向后移动,匹配串跳过  a*  
//主串不变,匹配模式串后2个字符,跳过a*
                match(str,i+1,length,pattern,j+2,length2)||
match(str,i,length,pattern,j+2,length2);
            }else{
                return match(str,i,length,pattern,j+2,length2);
            }
        }
        if(i<length&&(str[i]==pattern[j]||(pattern[j]=='.'))){
            return match(str,i+1,length,pattern,j+1,length2);//主串当前字符不为空,匹配或者匹配串为'.'
        }
        return false;
    }
}

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

public class Solution{
    public boolean isNumeric(char[] str){
        String s=String.valueOf(str);
        return s.matches("[\\+\\-]?[0-9]*(\\.[0-9]*)?([eE][\\+\\-]?[0-9]+)?");
    //  \为转义字符  + 表示出现至少一次 * 为出现0或多次 ?表示0或1 [  ]括号中的数选择出现
        //( )括号内的元素均要出现
    }
}

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

import java.util.*;
public class Solution{
    Map<Character,Integer> map=new HashMap<>();
    ArrayList<Character> list=new ArrayList<>();
    public void insert(char ch){
        if(map.containsKey(ch)){
            map.put(ch,map.get(ch)+1);
        }else
            map.put(ch,1);
        list.add(ch);
    }
    public char FirstAppear(){
        char ch="#";
        for(char key: list){
            if(map.get(key)==1){
                ch=key;
                break;
            }   
        }
        return ch;
    }
}

一个链表中包含环,请找出该链表的环的入口结点。

public class Solution{
    public ListNode EntryNodeOfLoop(ListNode pHead){
        if(pHead==null||pHead.next==null)
            return null;
        ListNode p1=pHead;
        ListNode p2=pHead;
//是否存在环或者找到环的入口,均采用‘快慢指针’的办法
        while(p1!=null&&p2.next!=null){
            p1=p1.next;
            p2=p2.next.next;
            if(p2==null)return null;
            if(p1==p2)
                break;
        }
        p1=pHead;
        while(p1!=p2){
            p1=p1.next;
            p2=p2.next; 
        }
        return p1;
    }
}

链表1->2->3->3->4->4->5 处理后为 1->2->5

public class Solution{
    public ListNode deleteDuplicate(ListNode pHead){
        if(pHead==null)
            return pHead;
        ListNode newHead=new ListNode(0);
        newHead.next=pHead;
        ListNode pre=newHead;
        ListNode cur=pHead;
        while(cur!=null){
            while(cur.next!=null&&cur.val==cur.next.val){
                cur=cur.next;   
            }
            if(pre.next==cur)
                pre=pre.next;
            else
                pre.next=cur.next;
            cur=cur.next;
        }
        return newHead.next;
    }
}

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

public class Solution{
    public TreeLinkNode getNext(TreeLinkNode pNode){
        if(pNode==null)
            return null;
        if(pNode.right!=null){
            //有右子树,则找右子树的最左节点
            pNode=pNode.right;
            while(pNode.left!=null)
                pNode=pNode.left;
            return pNode;
        }else{
//没有右子树,则找第一个当前节点是父节点的左子树的节点    
            while(pNode.next!=null){
                if(pNode.next.left==pNode){
                    return pNode.next;
            }
            pNode=pNode.next;//一直向上找
            }
        }
    }
}

对称的二叉树

public class Solution{
    boolean isSymmetrical(TreeNode pRoot){
        if(pRoot==null)
            return null;
        return isSymmetrical(pRoot.left,pRoot.right);
    }
    private boolean isSymmetrical(TreeNode pleft,TreeNode pright){
        if(pleft==null&&pright==null)
            return true;
        if(pleft==null||pright==null)
            return false;
        if(pleft.val==pright.val)
            return isSymmetrical(pleft.left,pright.right)&&isSymmetrical(pleft.right,pright.left);
        return false;
    }
}

按之字形顺序打印二叉树

public class Solution{
    public ArrayList<ArrayList<Integer>> print(TreeNode pRoot){
        ArrayList<ArrayList<Integer>>  result=new ArrayList<ArrayList<Integer>>();
        if(pRoot==null)
            return result;
        ArrayList<Integer> list=null;
        TreeNode node=null;
        LinkedList<TreeNode> stack1=new LinkedList<>();
        LinkedList<TreeNode> stack2=new LinkedList<>();
        stack1.add(pRoot);
        while(!stack1.isEmpty()){
            list=new ArrayList<>();
            while(!stack.isEmpty()){
                node=stack1.pop();
//将下一层的节点依次入stack,以便下次实现从右往左打印  

                if(node.left!=null)stack2.push(node.left);
                if(node.right!=null)stack2.push(node.right);
                list.add(node.val);
            }
            result.add(list);
            if(stack2.isEmpty())
                break;
            list=new ArrayList<>();
            while(!stack2.isEmpty()){
                node=stack2.pop();
                if(node.right!=null)stack1.push(node.right);
                if(node.left!=null)stack1.push(node.left);
                list.add(node.val);
            }
            result.add(list);
        }
        return result;      
    }
}

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
//队列LinkedList完成层序遍历,end记录每层节点个数

public class Solution{
    ArrayList<ArrayList<Integer>> print(TreeNode pRoot){
        ArrayList<ArrayList<Integer>> list=new ArrayList<>();
        ArrayList<Integer> lista=new ArrayList<Integer>();
        LinkedList<TreeNode> queue=new LinkedList<TreeNode>();
        if(pRoot==null)
            return list;
        queue.add(pRoot);
        int start=0,end=1;
        while(!queue.isEmpty()){
            TreeNode cur=queue.remove();
            lista.add(cur.val);
            start++;
            if(cur.left!=null)
                queue.add(cur.left);
            if(cur.right!=null)
                queue.add(cur.right);
            if(start==end){
                end=queue.size();
                start=0;
                list.add(lista);
                lista=new ArrayList<Integer>();
            }
        }
        return list;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值