1.二维数组中的查找2.替换空格3.从尾到头打印链表4.重建二叉树5.两个栈实现一个队列6.旋转数组中的最小值7.斐波那契数列8.二进制中1的个数

1.二维数组中的查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路:选取右上一点,若等于查找的数,则返回true,若此数大于所要查找的数,则此列都大于,不可能出现查找之数。剔除此列,以此类推。若右上角的数小于查找之数,则剔除此行。直到找到查找之数。

public class Main1 {
    public static boolean findNum(int[][] array,int target) {
        if(array == null) {
            return false;
        }
        int row = 0;
        int col = array[0].length - 1;
        while(row < array.length && col >= 0) {
            if(array[row][col] == target) {
                return true;
            }else if(array[row][col] > target) {
                col--;
            }else{
                row++;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int[][] arr = {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
        System.out.println(findNum(arr,7));
    }
}

2.替换空格

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

思路

  • 双指针法:先遍历一遍字符串,统计空格数,得出替换后长度,定义两个指针,p1指向字符串末尾,p2指向替换后末尾,把p1的内容拷贝到p2,同时减减。当p1遇到空格时,把空格替换为%20,p1向前移动一格,p2向前移动三格。

public class Main2 {
    public static String replaceSpace(StringBuffer str) {
        int spaceNum = 0;
        for(int i = 0;i < str.length();i++) {
            if(str.charAt(i) == ' '){
                spaceNum++;
            }
        }
        //记录字符串变化前后长度
        int oldLength = str.length();
        int newLength = str.length() + 2 * spaceNum;
        //重新设置str长度
        str.setLength(newLength);
        //定义两个指针
        int oldIndex = oldLength - 1;
        int newIndex = newLength - 1;
        while(oldIndex >= 0 && oldLength < newLength) {
            if(str.charAt(oldIndex) == ' ') {
                str.setCharAt(newIndex--,'0');
                str.setCharAt(newIndex--,'2');
                str.setCharAt(newIndex--,'%');
            }else {
                str.setCharAt(newIndex--,str.charAt(oldIndex));
            }
            oldIndex--;
        }
        return str.toString();
    }
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("we are happy!");
        System.out.println(replaceSpace(str));
    }
}

  • 用新的数组存:创建一个新数组,遍历字符串,当遇到空格时,插入%20,其他照搬,直至结束。
public class Main2 {
    public static String replaceSpace(StringBuffer str) {
        StringBuffer sb = new StringBuffer();
        for(int i = 0;i < str.length();i++) {
            if(str.charAt(i) == ' '){
                sb.append("%20");
            }else {
                sb.append(str.charAt(i));
            }
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("we are happy!");
        System.out.println(replaceSpace(str));
    }
}

3.从尾到头打印链表

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

思路:

  • 非递归,先进后出,用栈实现
import java.util.ArrayList;
import java.util.Stack;

public class Main3 {
    public class ListNode{
        int val;
        ListNode next = null;
        ListNode(int val) {
            this.val = val;
        }
    }
    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList list = new ArrayList();
        Stack stack = new Stack();
        while(listNode != null) {
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        while(!stack.empty()) {
            list.add(stack.pop());
        }
        return list;
    }
}
  • ArrayList 中有个方法是 add(index,value),可以指定 index 位置插入 value 值.每次插入0号位置
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList list = new ArrayList();
        while(listNode != null) {
            list.add(0,listNode.val);
            listNode = listNode.next;
        }
        return list;
    }
}
  • 递归解法
import java.util.ArrayList;
public class Main3 {
    ArrayList list = new ArrayList();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode != null) {
            printListFromTailToHead(listNode.next);
            list.add(listNode.val);
        }
        return list;
    }
}

4.重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

思路:前序遍历:根左右 ,中序遍历:左根右。前序遍历的第一个数为根,在中序遍历中找到该数,则之前的都是左子树,之后的都是右子树。运用递归的思想进行重建。

import java.util.Arrays;
public class Main4 {
    public static class TreeNode{
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) {
            val = x;
        }
    }
    public static TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre.length == 0 || in.length == 0) {
            return null;
        }
        if(pre.length != in.length)
            new Exception("前中序长度不同,请重新输入");
        TreeNode root = new TreeNode(pre[0]);

        for(int i = 0;i < in.length;i++) {
            if(in[i] == pre[0]) {
                root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i +1),
                        Arrays.copyOfRange(in,0,i));
                root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i + 1,pre.length),
                        Arrays.copyOfRange(in,i + 1,in.length));
            }
        }
        return root;
    }

    public static void main(String[] args) {
        int[] pre = {1,2,4,7,3,5,6,8};
        int[] mid = {4,7,2,1,5,3,8,6};
        System.out.println(reConstructBinaryTree(pre,mid));
    }
}

5.两个栈实现一个队列

用两个栈来实现一个队列,完成队列的appendTail和deleteHead操作。分别完成队列尾部插入节点和队列头部删除节点。

思路:栈为先进后出,所以尾部插入节点,就是将元素依次入栈,而删除头节点就是将第一次入栈的元素依次取出,在压入另一个栈,从第二个栈的栈顶取出要删除的节点。

import java.util.Stack;

public class Test {
    private Stack<Integer> stack1 = new Stack<>();
    private Stack<Integer> stack2 = new Stack<>();
    public void appendTail(int node){
        stack1.push(node);
        System.out.println(stack1);
    }
    public Integer deleteHead() throws Exception {
        if (stack2.isEmpty()){
            while (!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        if (stack2.isEmpty()){
            throw new Exception("队列为空,不能删除");
        }
        System.out.println(stack2);
        return stack2.pop();
    }
    public static void main(String[] args) throws Exception {
        Test test = new Test();
        test.appendTail(1);
        test.appendTail(2);
        test.appendTail(3);
        test.deleteHead();
    }
}

6.旋转数组中的最小值

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。

思路: 利用二分查找的方法,定义两个指针,left指向开始下标,right指向末尾下标,并求出中间值mid,若左下标对应的值小于中间值,则为递增数列,left = mid+1;若右下标对应的值大于中间值,则为递减数列,righ=mid;其他情况,left++.
注意特殊数组1,0,1,1,1,当左下标对应的值小于右下标对应的值,直接返回左下标对应的值.

public class Main6 {
    public static int minNumberInRotateArray(int [] array) {
        if(array.length == 1) {
            return array[0];
        }
        int left = 0;
        int mid = 0;
        int right = array.length - 1;
        while(left < right) {
            if(array[left] < array[right])
                return array[left];
            mid = left + (right - left)/2;
            if(array[mid] > array[left]) {
                left = mid + 1;
            }else if(array[mid] < array[right]) {
                right = mid;
            }else {
                left++;
            }
        }
        return array[left];
    }

    public static void main(String[] args) {
        int[] array1 = {3, 4, 5, 1, 2};
        System.out.println(minNumberInRotateArray(array1));
        int[] array2 = {1, 0, 1, 1, 1};
        System.out.println(minNumberInRotateArray(array2));
    }
}

7.斐波那契数列

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。

思路:后一个值是前两个值之和

public class Main7 {
    //递归版本
    public static int Fibonacci1(int n) {
        if(n <= 0) {
            return 0;
        }
        if(n <= 2) {
            return 1;
        }else {
            return Fibonacci1(n - 1) + Fibonacci1(n - 2);
        }
    }
    //非递归版本
    public static int Fibonacci2(int n) {
        if(n <= 0)
            return 0;
        if(n ==1||n == 2)
            return 1;
        int a = 1;
        int b = 1;
        int sum = 0;
        for(int i = 3;i <= n;i++) {
            sum = a + b;
            a = b;
            b = sum;
        }
        return sum;
    }
    public static void main(String[] args) {
        System.out.println(Fibonacci1(6));
        System.out.println(Fibonacci2(6));
    }
}

8.二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

思路:把一个整数减去1,在和原来的数做与运算,会把整数最右边的1变为0,那么一个数二进制中有多少个1,就有多少次操作

public class Main8 {
    public static int NumberOf1(int n) {
        int count = 0;
        while(n != 0) {
            count++;
            n = n & (n - 1);
        }
        return count;
    }

    public static void main(String[] args) {
        System.out.println(NumberOf1(9));
    }
}

发布了60 篇原创文章 · 获赞 23 · 访问量 3301

猜你喜欢

转载自blog.csdn.net/weixin_44945537/article/details/104852372
今日推荐