剑指offer 51~60

剑指offer 51~60

给定一个数组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.ArrayList;
public class Solution {
    public int[] multiply(int[] A) {
        int re[] = {0};
        if (A.length == 0 || A == null) return re;
        int len = A.length;
        int B[] = new int[len];
        int cnta = 1, cntb = 1;

        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len - 1; j++) {
                if (j < i) cnta *= A[j];
                else cntb *= A[j + 1];
            }
            B[i] = cnta * cntb;
            cnta = 1;
            cntb = 1;
        }
        return B;
    }
}
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        if (str == null || pattern == null) return false;
        return matchCore(str, 0, pattern, 0);
    }

    public boolean matchCore(char[] str, int s, char[] pattern, int p) {
        if (str.length <= s && pattern.length <= p) return true;    //都匹配完了
        if (str.length > s && pattern.length <= p) return false;    //模式完了,字符串还有

        if (p + 1 < pattern.length && pattern[p + 1] == '*') {
            //当前pattern的下一个是*号
            //字符串完了
            if (s >= str.length) return matchCore(str, s, pattern, p + 2);
            else {
                if (pattern[p] == str[s] || pattern[p] == '.') {
                    //当前位置匹配完成,移动到下一个串
                    return matchCore(str, s, pattern, p + 2)
                            || matchCore(str, s + 1, pattern, p + 2)
                            || matchCore(str, s + 1, pattern, p);
                } else return matchCore(str, s, pattern, p + 2);
            }
        }
        //当前pattern不是*的时候
        if (s >= str.length) return false;
        else {
            if (str[s] == pattern[p] || pattern[p] == '.') return matchCore(str, s + 1, pattern, p + 1);
        }
        return false;
    }
}
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+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) {
     // 如果这个数使用科学计数法表示,将数字分成两部分判断
        int posE = -1;
        if (contains(str, 'E') || contains(str, 'e')) {
            for (int i = 0; i < str.length; i++) {
                if (str[i] == 'E' || str[i] == 'e') {
                    posE = i;
                    break;
                }
            }
            //如果 'E' || 'e'在开始与结尾的位置,说明错误
            if (posE == 0 || posE == str.length - 1) return false;
            char left[] = new char[posE];
            char right[] = new char[str.length - posE - 1];
            left = subString(str, 0, posE);
            right = subString(str, posE + 1, str.length);
            // left判断与非科学计数法一样

            // right判断必须为整数
            if (startWith(right, '+') || startWith(right, '-')) {
                right = subString(right,1, right.length);
            }
            return isDecimal(left) && isDigit(right);
        } else return isDecimal(str);
    }

    static boolean isDigit(char[] num) {
        for (int i = 0; i < num.length; i++) {
            if (num[i] > '9' || num[i] < '0') return false;
        }
        return true;
    }

    static boolean contains(char[] str, char ch) {
        for (int i = 0; i < str.length; i++) {
            if (str[i] == ch) return true;
        }
        return false;
    }

    static boolean startWith(char[] str, char ch) {
        if (str[0] == ch) return true;
        return false;
    }

    static boolean isDecimal(char[] str) {
        if (startWith(str, '-') || startWith(str, '+')) {
            str = subString(str,1,str.length);
        }
        if (contains(str, '.')) {
            int posE = -1;
            for (int i = 0; i < str.length; i++) {
                if (str[i] == '.') {
                    posE = i;
                    break;
                }
            }
            if (posE == 0 || posE == str.length - 1) return true;
            char[] left = new char[posE];
            char[] right = new char[str.length - posE - 1];
            left = subString(str,0, posE);
            right = subString(str,posE + 1, str.length);
            return isDigit(left) && isDigit(right);
        } else return isDigit(str);
    }

    static char[] subString(char[] str, int start, int end) {
        char sta[] = new char[end - start];
        for (int i = start; i < end; i++) {
            sta[i - start] = str[i];
        }
        return sta;
    }
}
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。

public class Solution {
    
    char cn[] = new char[256];
    StringBuffer stringBuffer = new StringBuffer();

    public void Insert(char ch) {
        ++cn[ch];
        stringBuffer.append(ch + "");
    }

    public char FirstAppearingOnce() {
        char t[] = stringBuffer.toString().toCharArray();
        for(int i=0;i<t.length;i++){
            if(cn[t[i]]==1)return t[i];
        }
        return '#';
    }
}
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
/*
 public class ListNode {
    int val;
    ListNode next = null;

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

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if (pHead.next == null) return null;
        ListNode front = pHead;
        ListNode fallow = pHead;
        while (front.next != null) {
            front = front.next;
            fallow.next = null;
            fallow = front;
        }
        return front;
    }
}
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表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)
    {
        if (pHead == null) return null;
        ListNode preNode = null;
        ListNode node = pHead;
        while (node != null) {
            if (node.next != null && node.val == node.next.val) {
                int value = node.val;
                while (node.next != null && node.next.val == value) {
                    node = node.next;
                }
                if (preNode == null)
                    pHead = node.next;
                else
                    preNode.next = node.next;
            } else
                preNode = node;
            node = node.next;
        }
        return pHead;
    }
}
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
/*
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 pNode)
    {
        if (pNode == null) return null;
        if (pNode.right != null) {
            pNode = pNode.right;
            while (pNode.left != null) {
                pNode = pNode.left;
            }
            return pNode;
        }
        while (pNode.next != null) {
            if (pNode.next.left == pNode) {
                return pNode.next;
            }
            pNode = pNode.next;
        }
        return null;
    }
}
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    boolean isSymmetrical(TreeNode pRoot)
    {
        if (pRoot == null || pRoot.left == null && pRoot.right == null) return true;
        return isSymmetrical(pRoot.left, pRoot.right);
    }

    boolean isSymmetrical(TreeNode left, TreeNode right) {
        if (left == null && right == null) return true;
        if (left == null || right == null) return false;
        if (left.val == right.val)
            return isSymmetrical(left.left, right.right) && isSymmetrical(left.right, right.left);
        return false;
    }
}
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

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

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

    }

}
*/
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> nodelist = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> result = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        boolean isLeftToRight = true;
        int start = 0, end = 1;
        if (pRoot == null) return nodelist;
        queue.add(pRoot);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            result.add(node.val);
            start++;
            if (node.left != null) queue.add(node.left);
            if (node.right != null) queue.add(node.right);
            if (start == end) {
                if (!isLeftToRight) nodelist.add(revers(result));
                else nodelist.add(result);
                //下一行需要改变方向
                isLeftToRight = !isLeftToRight;
                end = queue.size();
                start = 0;
                result = new ArrayList<Integer>();
            }
        }
        return nodelist;
    }

    static ArrayList<Integer> revers(ArrayList<Integer> result) {
        ArrayList<Integer> res = new ArrayList<>();
        for (int i = result.size() - 1; i >= 0; i--) {
            res.add(result.get(i));
        }
        return res;
    }

}
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;


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

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

    }

}
*/
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
    ArrayList<ArrayList<Integer>> resultlist = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> result = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        int start = 0, end = 1;

        queue.add(pRoot);
        if (pRoot == null) return resultlist;
        while (!queue.isEmpty()) {
            TreeNode currentNode = queue.poll();
            result.add(currentNode.val);
            start++;
            if (currentNode.left != null) queue.add(currentNode.left);
            if (currentNode.right != null) queue.add(currentNode.right);
            if (start == end) {
                resultlist.add(result);
                start = 0;
                end = queue.size();
                result = new ArrayList<Integer>();
            }
        }
        return resultlist;
    }
    
}

猜你喜欢

转载自blog.csdn.net/qq_36986386/article/details/88347125