《程序员面试宝典》解题报告1-牛客

比较经典的一些题:
4、6、7、8、9、10、11、12、13、19、20、22、25、28、29、30

1.确定字符互异

题目描述
请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。

给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。

测试样例:
“aeiou”
返回:True
“BarackObama”
返回:False

import java.util.*;

public class Different {
    public boolean checkDifferent(String iniString) {
        // write code here
        char[] arr = iniString.toCharArray();
        Arrays.sort(arr);
        for(int i=1;i<arr.length;i++){
            if(arr[i] == arr[i-1]) return false;
        }
        return true;
    }
}

2、原串翻转

题目描述
请实现一个算法,在不使用额外数据结构和储存空间的情况下,翻转一个给定的字符串(可以使用单个过程变量)。

给定一个string iniString,请返回一个string,为翻转后的字符串。保证字符串的长度小于等于5000。

测试样例:
“This is nowcoder”
返回:“redocwon si sihT”

import java.util.*;

public class Reverse {
    public String reverseString(String iniString) {
        // write code here
        return new StringBuilder(iniString).reverse().toString();
    }
}

3、确定两串乱序同构

题目描述
给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。这里规定大小写为不同字符,且考虑字符串中的空格。

给定一个string stringA和一个string stringB,请返回一个bool,代表两串是否重新排列后可相同。保证两串的长度都小于等于5000。

测试样例:
“This is nowcoder”,“is This nowcoder”
返回:true
“Here you are”,“Are you here”
返回:false

import java.util.*;

public class Same {
    public boolean checkSam(String stringA, String stringB) {
        // write code here
        char[] A = stringA.toCharArray();
        char[] B = stringB.toCharArray();
        Arrays.sort(A);
        Arrays.sort(B);
        if(A.length != B.length) return false;
        for(int i=0;i<A.length;i++){
            if(A[i] != B[i]) return false;
        }
        return true;
    }
}

4、空格替换

题目描述
请编写一个方法,将字符串中的空格全部替换为“%20”。假定该字符串有足够的空间存放新增的字符,并且知道字符串的真实长度(小于等于1000),同时保证字符串由大小写的英文字母组成。

给定一个string iniString 为原始的串,以及串的长度 int len, 返回替换后的string。

测试样例:
"Mr John Smith”,13
返回:“Mr%20John%20Smith”
”Hello World”,12
返回:”Hello%20%20World”

import java.util.*;

public class Replacement {
    public String replaceSpace(String iniString, int length) {
        // write code here
        if(length == 0) return iniString;
        return iniString.replaceAll(" ","%20");
    }
}

5、基本字符串压缩

题目描述
利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能。比如,字符串“aabcccccaaa”经压缩会变成“a2b1c5a3”。若压缩后的字符串没有变短,则返回原先的字符串。

给定一个string iniString为待压缩的串(长度小于等于10000),保证串内字符均由大小写英文字母组成,返回一个string,为所求的压缩后或未变化的串。

测试样例
“aabcccccaaa”
返回:“a2b1c5a3”
“welcometonowcoderrrrr”
返回:“welcometonowcoderrrrr”

import java.util.*;

public class Zipper {
    public String zipString(String iniString) {
        // write code here
        int len = iniString.length();
        String zip = "";
        int count = 0;
        for(int i=1;i<=len;i++){
            char c = iniString.charAt(i-1);
            count = 1;
            while(i < len && iniString.charAt(i) == c){
                i++;
                count++;
            }
            zip = zip + String.valueOf(c) + count;
        }
        return zip.length() < iniString.length() ? zip : iniString;
    }
}

6、像素翻转

题目描述
有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度。

给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于500,图像元素小于等于256。

测试样例:
[[1,2,3],[4,5,6],[7,8,9]],3
返回:[[7,4,1],[8,5,2],[9,6,3]]

import java.util.*;
/**
先交换矩阵关于正对角线对称位置的值
再将矩阵每一行的值逆转
*/
public class Transform {
    public int[][] transformImage(int[][] mat, int n) {
        // write code here
        
        for(int i=0 ; i < n; i++){
            for(int j=i+1 ; j < n ; j++){
                int tmp = mat[i][j];
                mat[i][j] = mat[j][i];
                mat[j][i] = tmp;
            }
        }
        for(int i=0 ; i < n; i++){
            for(int j=0 ; j < n/2 ; j++){
                 int tmp = mat[i][j];
                 mat[i][j] = mat[i][n-j-1];
                 mat[i][n-j-1] = tmp;
            }
        }
        return mat;
    }
}

7、消除行列

题目描述
请编写一个算法,若N阶方阵中某个元素为0,则将其所在的行与列清零。

给定一个N阶方阵int[]mat和矩阵的阶数n,请返回完成操作后的int[][]方阵(C++中为vector>),保证n小于等于300,矩阵中的元素为int范围内。

测试样例:
[[1,2,3],[0,1,2],[0,0,1]]
返回:[[0,0,3],[0,0,0],[0,0,0]]

import java.util.*;

public class Clearer {
    public int[][] clearZero(int[][] mat, int n) {
        // write code here
        // First row has zero?
        int k = 0;
        while (k < n && mat[0][k] != 0) ++k;
        // Use first row/column as marker, scan the matrix
        for (int i = 1; i < n; ++i)
            for (int j = 0; j < n; ++j)
                if (mat[i][j] == 0)
                    mat[0][j] = mat[i][0] = 0;
        // Set the zeros
        for (int i = 1; i < n; ++i)
            for (int j = n - 1; j >= 0; --j)
                if (mat[0][j] == 0 || mat[i][0] == 0)
                    mat[i][j] = 0;
        // Set the zeros for the first row
        if (k < n) Arrays.fill(mat[0], 0);
        return mat;
    }
}

8、翻转子串

题目描述
假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。请将这个算法编写成一个函数,给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次检查子串的函数。

给定两个字符串s1,s2,请返回bool值代表s2是否由s1旋转而成。字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。

测试样例:
“Hello world”,"worldhello "
返回:false
“waterbottle”,“erbottlewat”
返回:true

import java.util.*;

public class ReverseEqual {
    public boolean checkReverseEqual(String s1, String s2) {
        // write code here
        return s1.length() == s2.length() && s1.concat(s1).indexOf(s2) >= 0;
    }
}

9、链表中倒数第k个结点

题目描述
输入一个链表,输出该链表中倒数第k个结点。

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
         if(head == null) return head;
         ListNode p = head;
         ListNode q = p;
         int i = 0;
         while(i < k && p != null){
             p = p.next;
             i++;
         }
         if(p == null && i < k) return null;
         while(p != null){
             p = p.next;
             q = q.next;
         }
        return q;
    }
}

10、访问单个节点的删除

题目描述
实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。
给定待删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true

import java.util.*;

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Remove {
    public boolean removeNode(ListNode pNode) {
        // write code here
        if(pNode.next == null) return false;
        int value = pNode.next.val;
        pNode.val = value;
        pNode.next = pNode.next.next;
        return true;
    }
}

11、链表分割

题目描述
编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。

import java.util.*;

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Partition {
    public ListNode partition(ListNode pHead, int x) {
        // write code here
        ListNode gtexPre = null,gtex = null;
        ListNode p = pHead,pre = null;
        while(p != null){            
            if(p.val >= x){
                if(gtex == null){
                    gtexPre = pre;
                    gtex = p;
                }
                pre = p;
            }
            else{
                if(gtex != null){
                    pre.next = p.next;
                    if(gtexPre != null){
                      gtexPre.next = p;
                   }else{
                        pHead = p;
                    }
                    p.next = gtex;
                    gtexPre = p;
                }
                else{
                    pre = p;
                }        
            }
            p = pre.next;
        }
        return pHead;
    }
}

12、链式A+B

题目描述
有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。
给定两个链表ListNode* A,ListNode* B,请返回A+B的结果(ListNode*)。
测试样例:
{1,2,3},{3,2,1}
返回:{4,4,4}

import java.util.*;
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Plus {
    public ListNode plusAB(ListNode a, ListNode b) {
        // write code here
        ListNode ans = a,pre = null;
        int tmp = 0;
        while(a != null && b != null){
            tmp = a.val + b.val + tmp;
            a.val = tmp % 10;
            tmp /= 10;
            pre = a;
            a = a.next;
            b = b.next;
        }
        if(a != null){
            while(tmp != 0 && a != null){
                tmp += a.val ;
                a.val = tmp % 10;
                tmp /= 10;
                pre = a;
                a = a.next;
            }
        }
        if(b != null){
            pre.next = b;
            while(tmp != 0 && b != null){
                tmp += b.val;
                b.val = tmp % 10;
                tmp /= 10;
                pre = b;
                b = b.next;
            }
        }
        if(tmp != 0){
            ListNode end = new ListNode(1);
            pre.next = end;
        }
        return ans;
    }
}

13、回文链表

题目描述
请编写一个函数,检查链表是否为回文。
给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试样例:
{1,2,3,2,1}
返回:true
{1,2,3,2,3}
返回:false

import java.util.*;

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

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

public class Palindrome {
    private ListNode partition(ListNode head){
        ListNode slow = head,fast = head.next;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode second = slow.next;
        slow.next = null;
        return second;
    }
    
    private ListNode reverse(ListNode head){
        ListNode p = head,pre = null,next = null;
        while(p != null){
            next = p.next;
            p.next = pre;
            pre = p;
            p = next;
        }
        return pre;
    }
    
    //p、q是等长链表
    private boolean areSame(ListNode p,ListNode q){
        while(p != null && q != null){
            if(p.val != q.val) return false;
            p = p.next;
            q = q.next;
        }
        return true;
    }
    
    public boolean isPalindrome(ListNode pHead) {
        // write code here
        if(pHead == null) return true;
        ListNode p = partition(pHead);
        p = reverse(p);
        return areSame(pHead,p);
    }
}

14、集合栈

题目描述
请实现一种数据结构SetOfStacks,由多个栈组成,其中每个栈的大小为size,当前一个栈填满时,新建一个栈。该数据结构应支持与普通栈相同的push和pop操作。
给定一个操作序列int[][2] ope(C++为vector&ltvector&ltint>>),每个操作的第一个数代表操作类型,若为1,则为push操作,后一个数为应push的数字;若为2,则为pop操作,后一个数无意义。请返回一个int[],为完成所有操作后的SetOfStacks,顺序应为从下到上,默认初始的SetOfStacks为空。保证数据合法。

import java.util.*;

public class SetOfStacks {
    ArrayList<ArrayList<Integer>> sst;
    int curr = 0;
    private void push(int x,int size){
        if(sst.get(curr).size() == size){
            curr++;
            if(curr == sst.size()){
                ArrayList<Integer> st = new ArrayList();
                sst.add(st);
            }
        }
        sst.get(curr).add(x);
    }
        
    private void pop(){
        if(sst.get(curr).size() == 0){
            if(curr == 0) return;
            curr--;
        }
        int length = sst.get(curr).size();
        sst.get(curr).remove(length-1);
    }
    
    public ArrayList<ArrayList<Integer>> setOfStacks(int[][] ope, int size) {
        // write code here
        sst = new ArrayList();
        curr = 0;
        ArrayList<Integer> st = new ArrayList();
        sst.add(st);
        if(ope == null || ope.length == 0) return sst;
        for(int i=0;i<ope.length;i++){
            if(ope[i][0] == 1){
                push(ope[i][1],size);
            }else{
                pop();
            }
        }
        return sst;
    }
}

15、两个栈实现队列

题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
       if(stack1.isEmpty() && stack2.isEmpty()) return -1;
       if(stack2.isEmpty()){
          while(!stack1.isEmpty()){
              stack2.push(stack1.pop());
          } 
       }
       return stack2.pop();
    }
}

16、双栈排序

题目描述
请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。
给定一个int[] numbers(C++中为vector&ltint>),其中第一个元素为栈顶,请返回排序后的栈。请注意这是一个栈,意味着排序过程中你只能访问到最后一个元素。
测试样例:
[1,2,3,4,5]
返回:[5,4,3,2,1]

import java.util.*;
/**
用ArrayList模拟栈,仅在位置0处操作数据
用数组模拟栈,指定一个栈顶指针top,仅在栈顶处操作
每次出栈A的栈顶元素x,再与另一个栈B的栈顶元素y比较,如果x>=y,则入栈;
如果x<y,
则循环出栈B的栈顶然后压入A
直到栈顶元素小于等于x,将x入栈B
*/
public class TwoStacks {
    public ArrayList<Integer> twoStacksSort(int[] numbers) {
        // write code here
        //栈顶指针
        int top = 0;
        
        ArrayList<Integer> stack = new ArrayList();
        
        int size = numbers.length;
        while(top < size){
            int x = numbers[top];
            top++;
            while(stack.size()!=0 &&  stack.get(0) > x){
                    numbers[--top] = stack.remove(0);     
            }
            stack.add(0,x);
        }
        return stack;
    }
}

17、猫狗收容所

题目描述
有家动物收容所只收留猫和狗,但有特殊的收养规则,收养人有两种收养方式,第一种为直接收养所有动物中最早进入收容所的,第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。
给定一个操作序列int[][2] ope(C++中为vector<vector>)代表所有事件。若第一个元素为1,则代表有动物进入收容所,第二个元素为动物的编号,正数代表狗,负数代表猫;若第一个元素为2,则代表有人收养动物,第二个元素若为0,则采取第一种收养方式,若为1,则指定收养狗,若为-1则指定收养猫。请按顺序返回收养的序列。若出现不合法的操作,即没有可以符合领养要求的动物,则将这次领养操作忽略。
测试样例:
[[1,1],[1,-1],[2,0],[2,-1]]
返回:[1,-1]

import java.util.*;

public class CatDogAsylum {
    public ArrayList<Integer> asylum(int[][] ope) {
        // write code here
        ArrayList<Integer> animals = new ArrayList();
        ArrayList<Integer> adopts = new ArrayList();
        for(int[] op : ope){
            if(op[0] == 1){
                animals.add(op[1]);
            }else if(op[0] == 2){
                if(op[1] == 0){
                    adopts.add(animals.remove(0));
                }
                else if(op[1] == 1 || op[1] == -1){
                    for(Integer pet : animals){
                        if(pet*op[1] > 0){
                            animals.remove(pet);
                            adopts.add(pet);
                            break;
                        }
                    }
                }
            }
        }
        return adopts;
    }
}

18、二叉树平衡检查

题目描述
实现一个函数,检查二叉树是否平衡,平衡的定义如下,对于树中的任意一个结点,其两颗子树的高度差不超过1。
给定指向树根结点的指针TreeNode* root,请返回一个bool,代表这棵树是否平衡。

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class Balance {
    private int depth(TreeNode root){
        if(root == null) return 0;
        return 1+Math.max(depth(root.left),depth(root.right));
    }
    public boolean isBalance(TreeNode root) {
        // write code here
        if(root == null) return true;
        int l = depth(root.left);
        int r = depth(root.right);
        return (Math.abs(l - r)<=1) && isBalance(root.left) && isBalance(root.right);
    }
}

19、有向路径检查

题目描述
对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径。
给定图中的两个结点的指针DirectedGraphNode* a, DirectedGraphNode* b(请不要在意数据类型,图是有向图),请返回一个bool,代表两点之间是否存在一条路径(a到b或b到a)。

import java.util.*;

/*
public class UndirectedGraphNode {
    int label = 0;
    UndirectedGraphNode left = null;
    UndirectedGraphNode right = null;
    ArrayList<UndirectedGraphNode> neighbors = new ArrayList<UndirectedGraphNode>();

    public UndirectedGraphNode(int label) {
        this.label = label;
    }
}*/
/*
**什么问题呢,做题做傻了,我还去加了个
visit.remove语句,导致一直超时,最后才发现问题所在
这种题真的是再简单不过的图遍历,但做出来的感觉就是很不错
*/
public class Path {
    private boolean checkPath(UndirectedGraphNode start, UndirectedGraphNode end,
                              ArrayList<Integer> visit){
        if(start.label == end.label){
            return true;
        }
        visit.add(start.label);
        ArrayList<UndirectedGraphNode> neighbors = start.neighbors;
        for(UndirectedGraphNode neighbor:neighbors){
            if(!visit.contains(neighbor.label)){
                if(checkPath(neighbor,end,visit))
                    return true;
            }
        }
        return false;
    }
    public boolean checkPath(UndirectedGraphNode a, UndirectedGraphNode b) {
        // write code here
        ArrayList<Integer> visit = new ArrayList();
        if(checkPath(a,b,visit)) return true;
        visit.clear();
        return checkPath(b,a,visit);
         
    }
}

20、高度最小的BST

题目描述
对于一个元素各不相同且按升序排列的有序序列,请编写一个算法,创建一棵高度最小的二叉查找树。
给定一个有序序列int[] vals,请返回创建的二叉查找树的高度。

import java.util.*;

public class MinimalBST {
    public int buildMinimalBST(int[] vals) {
        // write code here
        if(vals == null) return 0;
        int len = vals.length;
        int height = 0;
        while(len > 0){
            len /= 2;
            height++;
        }
        return height;
    }
}

21、输出单层节点

题目描述
对于一棵二叉树,请设计一个算法,创建含有某一深度上所有结点的链表。
给定二叉树的根结点指针TreeNode* root,以及链表上结点的深度,请返回一个链表ListNode,代表该深度上所有结点的值,请按树上从左往右的顺序链接,保证深度不超过树的高度,树上结点的值为非负整数且不超过100000。

import java.util.*;

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

    ListNode(int val) {
        this.val = val;
    }
}*/
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class TreeLevel {
    public ListNode getTreeLevel(TreeNode root, int dep) {
        // write code here
        if(root == null || dep <= 0) return null;
        int currdep = 0;
        Queue<TreeNode> q = new LinkedList();
        ListNode tail = null,head = null;
        q.offer(root);
        while(!q.isEmpty() && currdep < dep){
            currdep++;
            int size = q.size();
            for(int i=0; i < size; i++){
                TreeNode t = q.poll();
                if(t.left != null) q.offer(t.left);
                if(t.right != null) q.offer(t.right);
                if(currdep == dep){
                    ListNode node = new ListNode(t.val);
                    if(head == null){
                        head = node;
                    }
                    if(tail != null){
                        tail.next = node;
                    }
                    tail = node;
                }
            }           
        }
        return head;
    }
}

22、检查是否为BST

题目描述
请实现一个函数,检查一棵二叉树是否为二叉查找树。
给定树的根结点指针TreeNode* root,请返回一个bool,代表该树是否为二叉查找树。

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class Checker {
    public int flag = 0;
    public double pre = -Double.MAX_VALUE;


    public void PostOrder(TreeNode root){
         if(root.left != null)
            PostOrder(root.left);
         
         if(root.val <= pre){
           flag = 1;
           return ;
         }
         else 
            pre = root.val;

         if(root.right != null)
           PostOrder(root.right);
    }
    public boolean checkBST(TreeNode root) {
        if(root != null){
           PostOrder(root);
           return flag == 0;
        }
        
        return true;
    }
    public boolean checkBST2(TreeNode root) {
        // write code here 
        if(root == null) return true;
        
        TreeNode p = root;
        Stack<TreeNode> st = new Stack();
        //root.val-1 可能越界
        double pre = -Double.MAX_VALUE;
        while(p != null || !st.isEmpty()){
            while(p != null){
                st.push(p);
                p = p.left;
            }
            p = st.pop();
            if(p.val <= pre) return false;
            else{
                pre = p.val;
            }
            p = p.right;
        }
        return true;
    }
}

23、寻找下一个节点

题目描述
请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值。保证结点的值大于等于零小于等于100000且没有重复值,若不存在后继返回-1。

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
/*
*中序遍历非递归
*/
public class Successor {
    public int findSucc(TreeNode root, int p) {
        // write code here
       Stack<TreeNode> st = new Stack();
       TreeNode t = root;
       boolean isNext = false;
       while(t != null || !st.isEmpty()){
           while(t != null){
               st.push(t);
               t = t.left;
           }
           t = st.pop();
           if(isNext) return t.val;
           if(t.val == p) isNext = true;
           t = t.right;
       }
       return -1;
    }
}

24、最近公共祖先

题目描述
有一棵无穷大的满二叉树,其结点按根结点一层一层地从左往右依次编号,根结点编号为1。现在有两个结点a,b。请设计一个算法,求出a和b点的最近公共祖先的编号。
给定两个int a,b。为给定结点的编号。请返回a和b的最近公共祖先的编号。注意这里结点本身也可认为是其祖先。
测试样例:
2,3
返回:1

import java.util.*;

public class LCA {
    public int getLCA(int a, int b) {
        // write code here
        while(a != b){
            if(a > b){
                a /= 2;
            }
            else{
                b /= 2;
            }
        }
        return a;
    }
    
}

25、二叉树中和为某一值的路径

题目描述
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    private void FindPath(TreeNode root,int curr,int target, ArrayList<Integer> list, ArrayList<ArrayList<Integer>> ans){
        if(root == null) return;
        curr += root.val;
        if(root.left == null && root.right == null){
            if(curr == target){
                 list.add(root.val);
                 ans.add(new ArrayList(list));
                 list.remove(list.size()-1);
            }
            return;
        }
        list.add(root.val);
        FindPath(root.left,curr,target,list,ans);
        FindPath(root.right,curr,target,list,ans);
        list.remove(list.size()-1);
    }
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();
        if(root != null){
             ArrayList<Integer> list = new ArrayList();
            int curr = 0;
            FindPath(root,curr,target,list,ans);
        }
        return ans;
    }
}

26、二进制插入

题目描述
有两个32位整数n和m,请编写算法将m的二进制数位插入到n的二进制的第j到第i位,其中二进制的位数从低位数到高位且以0开始。
给定两个数int n和int m,同时给定int j和int i,意义如题所述,请返回操作后的数,保证n的第j到第i位均为零,且m的二进制位数小于等于i-j+1。
测试样例:
1024,19,2,6
返回:1100

import java.util.*;

public class BinInsert {
    public int binInsert(int n, int m, int j, int i) {
        // write code here
        return n + m * (int)Math.pow(2,j);
    }
}

27、二进制小数

题目描述
有一个介于0和1之间的实数,类型为double,返回它的二进制表示。如果该数字无法精确地用32位以内的二进制表示,返回“Error”。
给定一个double num,表示0到1的实数,请返回一个string,代表该数的二进制表示或者“Error”。
测试样例:
0.625
返回:0.101

import java.util.*;

public class BinDecimal {
    public String printBin(double num) {
        // write code here
        int i=32;
        String exp = "";
        double tmp = 1.0;
        while(i > 0 && num != 0){
            tmp /= 2;
            i--;
            if(tmp <= num){
                exp += "1";
                num -= tmp;
            }else{
                exp += "0";
            }
        }
        return num == 0 ? "0."+exp : "Error";
    }
}

28、最接近的数

题目描述
有一个正整数,请找出其二进制表示中1的个数相同、且大小最接近的那两个数。(一个略大,一个略小)
给定正整数int x,请返回一个vector,代表所求的两个数(小的在前)。保证答案存在。
测试样例:
2
返回:[1,4]

import java.util.*;

public class CloseNumber {
    public int[] getCloseNumber(int x) {
        // write code here
        int max = x+1;
        int min = x-1;
        int count = Integer.bitCount(x);
        while(count != Integer.bitCount(max)){
            max++;
        }
        while(count != Integer.bitCount(min)){
            min--;
        }
        return new int[]{min,max};
    }
}

29、整数转化

题目描述
编写一个函数,确定需要改变几个位,才能将整数A转变成整数B。
给定两个整数int A,int B。请返回需要改变的数位个数。
测试样例:
10,5
返回:4

import java.util.*;
/**
转化为两数异或的值中1的个数
**/
public class Transform {
    public int calcCost(int A, int B) {
        // write code here
        int num = A ^ B;
        int count = 0;
        while(num != 0){
            count++;
            num = num & (num-1);
        }
        return count;
    }
}

30、奇偶位交换

题目描述
请编写程序交换一个数的二进制的奇数位和偶数位。(使用越少的指令越好)
给定一个int x,请返回交换后的数int。
测试样例:
10
返回:5

import java.util.*;

public class Exchange {
    public int exchangeOddEven(int x) {
        // write code here
        return ((x & 0x55555555) << 1) | ((x & 0xaaaaaaaa) >>> 1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wsws100

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值