剑指Offer

丑数

public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index==0) return 0;
        if(index==1) return 1;
        int [] res = new int [index];
        res[0] = 1;
        int res_i = 1;
        int i = 0, j = 0, k = 0;
        while(res_i<index){
            int t = Math.min(res[i]*2,Math.min(res[j]*3,res[k]*5));
            res[res_i++] = t;
            if(res[i]*2 == t) i++;
            if(res[j]*3 == t) j++;
            if(res[k]*5 == t) k++;
        }
        return res[index-1];
    }
}

 

字符中第一个只出现一次的字符

tips:

Java获取字符串长度(length())

Map<Character, Integer> map = new HashMap<Character, Integer>();

import java.util.HashMap;
import java.util.Map;
public class Solution {
    public int FirstNotRepeatingChar(String str) {
            int len = str.length();
            if(len == 0 ) return -1;
            Map<Character, Integer> map = new HashMap<Character, Integer>();
            int i = 0;
            //str.charAt(i) != '\0' 这样好像不对,但是为啥呢?
            while(i<len){
                //如果已经存在该字母
                if(map.containsKey(str.charAt(i))){
                    int count = map.get(str.charAt(i));
                    count++;
                    map.put(str.charAt(i),count);
                }else{
                    map.put(str.charAt(i),1);
                }
                i++;
            }
            //循环遍历字符串,找到结果(比循环遍历数组好一点吧)
            for(int j = 0;j<len;j++){
                if(1 == map.get(str.charAt(j))){
                    return j;
                }
            }

            return -1;
        }
}

字符流中第一个只出现一次的字符

import java.util.*;
public class Solution {
    Map<Character, Integer> map = new HashMap<Character, Integer>();
    Queue<Character> queue = new LinkedList<Character>();
    //Insert one char from stringstream
    public void Insert(char ch)
    {
        if(map.containsKey(ch)){
            //已经存在过,就不插入队列中,并且把队列头中count>1的删除(错误:与该字符相等的)都删除
            int count = map.get(ch)+1;
            map.put(ch,count);
            while((!queue.isEmpty()) && map.get(queue.peek())>1){//****
                queue.poll();
            } 
        }else{
            //没有存在过,就加入map,加入队尾
            map.put(ch,1);
            queue.offer(ch);
        }
    }
    //return the first appearence once char in current stringstream
    public char FirstAppearingOnce()
    {
        if(queue.isEmpty()) return '#';
        return queue.peek();
    }

}

数组中的逆序对

public class Solution {
    public int merge(int [] array , int l ,int r, int [] temp){
        if(l>=r) return 0;
        int mid = (l+r)>>1;
        int res = merge(array,l,mid , temp) + merge(array , mid + 1,r, temp);
        if(res>=1000000007)//数值过大求余
        {
            res%=1000000007;
        }
        int i = l,j = mid+1;
        int t = 0;
        while(i<=mid && j<=r){
            if(array[i]<=array[j]){
                temp[t++] = array[i];
                i++;
            }else{
                temp[t++] = array[j];
                res += mid-i+1;
                if(res>=1000000007)//数值过大求余
                {
                    res%=1000000007;
                }
                j++;
            }
        }
        while(i<=mid) temp[t++] = array[i++];
        while(j<=r) temp[t++] = array[j++];
        i = l; t = 0;
        while(i<=r) array[i++] = temp[t++];
        return res;
    }
    public int InversePairs(int [] array) {
        if(null == array || array.length == 0) return 0;
        int [] temp = new int [array.length];
        int res = merge(array , 0 , array.length-1,temp)%1000000007;
        return res;
    }
}

两个链表的第一个公共节点

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode p = pHead1;
        ListNode q = pHead2;
        while(p!=q){
            if(p!=null) p = p.next;//错误:p = p->next
            else p = pHead2;
            if(q!=null) q = q.next;
            else q = pHead1;
        }
        return p;
    }
}

数字在排序数组中出现的次数

public class Solution {
    public int GetNumberOfK(int [] array , int k) {
        if(null == array || array.length==0) return 0;
        int l = 0, r = array.length-1;
        while(l<r){
            int mid = (l+r) >>1;
            if(array[mid]<k) l = mid+1;
            else r = mid;
        }
        if(array[l]!=k) return 0;
        int left = l;
        
        l = 0;
        r = array.length-1;
        while(l<r){
            int mid = (l+r+1) >>1;
            if(array[mid]<=k) l = mid;
            else r = mid-1;
        }
        return r-left+1;
    }
}

二叉搜索树的第k个节点

/*
题目描述:给定一棵二叉搜索树,请找出其中的第k小的结点。
例如, (5,3,7,2,4,6,8)    中,
按结点数值大小顺序第三小结点的值为4
*/
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    TreeNode res = null;
    int i = 0;
    TreeNode KthNode(TreeNode pRoot, int k)
    {
        if(pRoot == null) return null;
        res = KthNode(pRoot.left,k);
        i++;//本来这里是用k--,来判断,但是这里是值传递,就设置了一个全局变量
        if(i==k) res = pRoot;
        if(i<k) res = KthNode(pRoot.right,k);
        return res;
    }
}

二叉树的深度

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    public int TreeDepth(TreeNode root) {
        if(root == null) return 0;
        return Math.max(TreeDepth(root.left),TreeDepth(root.right))+1;
    }
}

平衡二叉树

public class Solution {
    boolean res = true;
    public boolean IsBalanced_Solution(TreeNode root) {
        Height_Tree(root);
        return res;
    }
    public int Height_Tree(TreeNode root){
        if(root == null) return 0;
        int left = Height_Tree(root.left);
        int right = Height_Tree(root.right);
        if(Math.abs(left-right) >1) res = false;
        return Math.max(left , right )+1;
    }
}

数组中只出现一次的数字

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        //先求所有数的异或和
        int sum = 0;
        for(int i = 0;i < array.length;i++) sum ^= array[i];
        //找sum中第k位:即不为零的位置
        int k = 0;
        while(((sum>>k)&1) == 0) k++;//注意这里要都加上括号,以防错误
        //第一个集合
        num1[0] = 0;
        for(int i = 0;i<array.length;i++){
            if(((array[i]>>k)&1) == 1) num1[0] ^= array[i];
        }
        num2[0] = sum ^ num1[0];
    }
}

和为S的两个数

import java.util.ArrayList;
import java.util.HashSet;//这个要加上
public class Solution {
    public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        HashSet hashSet = new HashSet();
        int min = 0;
        int max = 0;
        boolean zhaodao = false;
        int ji = Integer.MAX_VALUE;
        for(int i = 0;i<array.length;i++){
            if(hashSet.contains(sum-array[i])){
                zhaodao = true;
                int t_ji = (sum-array[i])*array[i];
                if(t_ji<ji){
                    min = sum-array[i];
                    max = array[i];
                }
            }
            hashSet.add(array[i]);
        }
        if(zhaodao){
            arrayList.add(min);
            arrayList.add(max);
        }
        return arrayList;
        
    }
}

和为S的连续正数序列

import java.util.ArrayList;
public class Solution {
    public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> array_res = new ArrayList<ArrayList<Integer>>();
        for(int i = 1,j = 1, s = 1; i<=sum;i++){
            while(s<sum) s += ++j;
            if(s==sum && (j-i)>=1){//(j-i)>=1 这一截一定要加上
                ArrayList<Integer> array_temp = new ArrayList();
                for(int k = i;k<=j;k++) array_temp.add(k);
                array_res.add(array_temp);
            }
            s -= i;
        }
        return array_res;
    }
}

翻转单词序列

tips:

java如何修改String中的一个字符

    String str = "Test string";
    StringBuilder strBuilder = new StringBuilder(str);
    strBuilder.setCharAt(1, 'X');
    str=Builder.toString();

String不可变
StringBuilder可变

参考:
http://stackoverflow.com/questions/4576513/str-setcharatindex-x
http://www.cnblogs.com/fancydeepin/archive/2013/04/23/min-snail-speak_string-stringbuffer-stringbuilder.html

 

public class Solution {
    public static String ReverseSentence(String str) {
        StringBuilder strBuilder = new StringBuilder(str);
        if(strBuilder.length()==0 || strBuilder.length()==1) return str;
        //整个字符串翻转
        for(int i =0 , j = strBuilder.length()-1;i<j;i++,j--){
            char ch = strBuilder.charAt(i);
            strBuilder.setCharAt(i,strBuilder.charAt(j)) ;
            strBuilder.setCharAt(j,ch);
        }
        //把每个单词翻转
        for(int i = 0; i<strBuilder.length();){
            int j = i;
            while(j<strBuilder.length() && strBuilder.charAt(j)!=' ') j++;
            System.out.println(i);
            System.out.println(j);
            for(int p = i ,q = j-1 ; p < q ; p++ ,q--){
                char ch = strBuilder.charAt(p);
                strBuilder.setCharAt(p,strBuilder.charAt(q)) ;//一开始总是错,是因为这里面写的是str而不是strBuilder
                strBuilder.setCharAt(q,ch);
            }
            i = j+1;
            //break;
        }
        str=strBuilder.toString();
        return str;
    }
}

左旋转字符串

public class Solution {
    public String LeftRotateString(String str,int n) {
        StringBuilder strBuilder = new StringBuilder(str);
        if(strBuilder.length()==0 || strBuilder.length()==1) return str;
        //整个字符串翻转
        for(int i =0 , j = strBuilder.length()-1;i<j;i++,j--){
            char ch = strBuilder.charAt(i);
            strBuilder.setCharAt(i,strBuilder.charAt(j)) ;
            strBuilder.setCharAt(j,ch);
        }
        //再把两部分翻转
        for(int i =0 , j = strBuilder.length()-n-1;i<j;i++,j--){
            char ch = strBuilder.charAt(i);
            strBuilder.setCharAt(i,strBuilder.charAt(j)) ;
            strBuilder.setCharAt(j,ch);
        }
        for(int i =strBuilder.length()-n, j = strBuilder.length()-1;i<j;i++,j--){
            char ch = strBuilder.charAt(i);
            strBuilder.setCharAt(i,strBuilder.charAt(j)) ;
            strBuilder.setCharAt(j,ch);
        }
        
        str=strBuilder.toString();
        return str;
    }
    
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值