java面试编程(手撕代码)

12 篇文章 0 订阅
9 篇文章 0 订阅

剑指offer:
JZ1-二维数组查找
在这里插入图片描述
思路一

##二分查找-把每一行看成有序递增的数组,利用二分查找,通过遍历每一行得到答案,时间复杂度是nlogn
public class Solution{
       public boolean Find(int target, int [][] array){
              for(int i=0;i<array.length;i++){
              int low=0;
              int high=array[i].length-1;
              while(low<=high){
                int mid=(low+high)/2;
                if(target>array[i][mid])
                    low=mid+1;
                else if(target<array[i][mid])
                    high=mid-1;
                else 
                    return true; 
               }
              }
              return false;
       }
}

思路二

#利用二维数组由上到下,由左到右递增的规律,那么选取右上角或者左下角的元素a[row][col]与target进行比较,
#当target小于元素a[row][col]时,那么target必定在元素a所在行的左边,
#即col--;
#当target大于元素a[row][col]时,那么target必定在元素a所在列的下边,
#即row++public class Soution{
    public boolean Find(int[][]array,int target){
    int row=0;
    int col=array[0].length-1;
    while(row<=array.length-1&&col>=0){
       if(target==array.length[row][col])
            return true;
       else if(target>array[row][col])
           row++;//缩小范围
       else
           col--;
     }
     return false;
}
}

JZ2-替换空格
在这里插入图片描述

/*
问题1:替换字符串,是在原来的字符串上做替换,还是新开辟一个字符串做替换!
问题2:在当前字符串替换,怎么替换才更有效率(不考虑java里现有的replace方法)。
      从前往后替换,后面的字符要不断往后移动,要多次移动,所以效率低下
      从后往前,先计算需要多少空间,然后从后往前移动,则每个字符只为移动一次,这样效率更高一点。
      空格替换成%20
      例如:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
      从后往前补充
*/
public class Solution{
       public String replaceSpace(StringBuffer str){
          int spacenum=0;//计算空格数
          for(int i=0;i<str.length();i++){
              if(str.charAt(i)==' ')
              spacenum++;//有一个空格就增加
          }
          int indexold=str.length()-1;
          int newlength=str.length()+spacenum*2;//替换的占有三个空间,加上原来永远有的一个空格空间,只需要再补充两个空间即可
          int indexnew=newlength-1;//先计算好需要补充多少空格
          str.setLength(newlength);//使str的长度扩大到转换成%20之后的长度,防止下标越界
                                   //扩容
          for(;indexold>=0&&indexold<newlength;--indexold){
                 if(str.charAt(indexold)==' '){
                  str.setCharAt(indexnew--,'0');//从后往前,所以需要自减
                  str.setCharAt(indexnew--,'2');//setCharAt将字符放到指定的位置
                  str.setCharAt(indexnew--,'%');
                  
                  }else{
                     str.setCharAt(indexnew--,str.charAt(indexold));
                   }
          }
          return str.toString();
       }
}

JZ3-从尾到头打印链表
在这里插入图片描述
方法一

public class Solution{
  ArrayList<Integer>arrayList=new ArrayList<Integer>();
  public ArrayList<Integer>printListFromTailToHead(ListNode listNode){
    if(listNode!=null){
         this.printListFromTailToHead(listNode.next);
         arrayList.add(listNode.val);
    }
    return arrayList;
  }
}

方法二:

import java.util.ArrayList;
import java.util.Collections;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> list = new ArrayList<Integer>();
         
        while(listNode != null){
            list.add(listNode.val);
            listNode = listNode.next;
        }
         
        Collections.reverse(list);//使用Collections的reverse方法,直接将list反转
        return list;
    }
}

JZ-4-重建二叉树
在这里插入图片描述

public class Solution{
       public TreeNode reConstructBinaryTree(int[]pre,int[] in){//前序遍历和中序遍历序列
         TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
         return root;
       }
        //前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
       private TreeNode reConstructBinaryTree(int[] pre,int startPre,int endPre,int[] i,int startIn,int endIn){
                                              // 前序    前序开始 前序结束                      中序开始 中序结束
 
         if(startPre>endPre||startIn>endIn)
             return null;
         TreeNode root=new TreeNode(pre[startPre]);//根节点是前序的第一个节点
         
         for(int i=startIn;i<=endIn;i++) //i是中序的节点,从中序的节点从前往后遍历
            if(in[i]==pre[startPre]){//中序的第一个节点与中序的节点相等的确定根节点
              root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);//找出对应的左节点和右节点
                                              //
              root.rigth=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in.i+1,endIn);
                   break;
            }
            return root;
       }
}

JZ5-用两个栈实现队列

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(stack!.empty()&&stack2.empty()){
             throw new RuntimeException("Queue is empty");
             }
             if(stack2.empty()){
                while(!stack1.empty()){
                  stack2.push(stack1.pop());
                 }
              }
              return stack2.pop();
    }
    }
                               
         //1 2 3 4 5进栈1  结果从下往上分别是 1 2 3 4 5
         //取stack1栈顶元素分别 5 4 3 2 1 分别进stack2  顺序从下向上是 5 4 3 2 1
         //栈2出栈 顺序使1 2 3 4 5 和最初结果一样

empty() 堆栈为空则返回真

pop() 移除栈顶元素

push() 在栈顶增加元素

size() 返回栈中元素数目

top() 返回栈顶元素

JZ6-旋转数组中的最小数字
在这里插入图片描述
本质就是找到数组中最小的值

public class Solution{//二分查找
   public int minNumberInRotateArray(int[]array){
     int low=0;int high=array.length-1;
     while(low<high){
       int mid=low+(high-low)/2;
       if(array[mid]>array[high]){
          low=mid+1;
        }else{
          high=mid;
         }
      }
      return array[low];
    }
  }

JZ7-斐波那契数列
在这里插入图片描述

#循环实现
public class Solution{
    public int Fibonacci(int n){
     int preNum=1;
     int prePreNum=0;
     int result=0;
     if(n==0)
       return 0;
     if(n==1)
       return 1;
     for(int i=2;i<=n;i++){
        result=preNum+prePreNum;
        prePreNum=preNum;
        preNum=result;
      }
      return result;
     }
 }

JZ8-跳台阶
在这里插入图片描述

public class Solution{
    public int JumpFloor(int target){
     if(target==1)
        return 1;
     int f1=1,f2=1,ret=0;
     for(int i=2;i<=target;i++){
      ret=f1+f2;
      f1=f2;
      f2=ret;
      }
      return ret;
     }
 }

JZ9-变态跳台阶
在这里插入图片描述
在这里插入图片描述

public class Solution{
       public int JumpFloorII(int target){
         if(target<=0){
            return -1;
          }else if(target==1){
           return 1;
           }else{
              return 2*JumpFloorII(target-1);
            }
       }
}

JZ-10矩形覆盖
在这里插入图片描述

public class Solution{
     public int RectCover(int target){
        if(target<3){
            return target;
         }
         return RectCover(target-1)+RectCover(target-2);
     }
 }

JZ-11 二进制中1的个数
在这里插入图片描述

public class Solution{
     public int NumberOf1(int n){
      int sum=0;
      while(n!=0)
      {
          sum++;
          n=(n-1)&n;
       }
       return sum;
      }
 }

JZ-12 数值的整数次方
在这里插入图片描述
5^2 整数的求幂运算

public class Solution{
   public double Power(double base,int exponent){ //底 - 指数
     if(exponent==0) return 1  //指数为0,直接输出1 1 ^0=1
     if(Math.abs(base)<=0.000000000001) return 0;//Math.abs 绝对值 底为0  则0^5=0
 
      boolean reverseFlag=exponent<0;//指数为负数,则结果要求取倒数
      exponent=Math.abs(exponent);//先对负数求取绝对值
      double result=1;
       
      while(exponent-- >0){ //现在确定指数的值均为正
          result *=base;//result =result*base
        }
        return reverseFlag?1/result:result;//负数就是求倒数  整数就是正常结果
    }
 }

JZ-13调整数组顺序的使得奇数位于偶数之前
在这里插入图片描述
奇数偶数数组数据分离

public class Solution{
   public void reOrderArray(int[] array){
     for(int i=0;i<array.length-1;i++)//i的目的是对当前未知上的元素进行偶奇交换 之后遍历数组上的每个点,确保偶奇交换彻底
         for(int j=0;j<array.length-1;j++){
             if(array[j]%2==0&&array[j+1]%2==1){//j偶数 j+1奇数 偶数奇数就交换未知
               int temp=array[j];
               array[j]=array[j+1];
               array[j+1]=temp;
              }
          }
    }
 }

JZ-14 链表中倒数第K个节点。
在这里插入图片描述
倒数的话,思路都应该反过来

public class Solution{
   public ListNode FindKthToTail(ListNode head,int k){ 
      ListNode p,q;//定义两个链表
      p=q=head;//定义两个链表的头节点
      int i=0;
      for(;p!=null;i++){
          if(i>=k){
             q=q.next;
             p=p.next
           }
           return i<k?null:q;
       }
    }
 }

方法二:

public class Solution{
   public ListNode FindKthToTail(ListNode head,int k){
       ListNode pre=null,p=null
       p=head;
       pre=head;
       //记录k值
       int a=k;
       //记录节点个数
       int count=0;
       while(p!=null){
        p=p.next;//这两个链表是一样的,然后p先跑,
        count++;
        if(k<1){
          pre=pre.next;//k=0 那么倒数第一个节点即是满足的条件
         }
         k--; // 4 3 2 1 0 -1 -2 
        }
        if(count<a)return null;
        return pre;
    }
 }

JZ-16 反转链表
在这里插入图片描述

public class Solution{
  public ListNode ReverseList(ListNode head){
      if(head==null)
         return null;
      ListNode p=head.next;
      ListNode res=null;//设置一个新链表
      while(head!=null){
        head.next=res;
        res=head;
        head=p;
        if(head!=null)
            p=head.next;
       } 
      return res;
   }
 }
public class Solution{
    public ListNode ReverseList(ListNode head){
       if(head==null)
           return null;
       ListNode pre=null;
       ListNode next=null;
         //当前节点是head,pre为当前节点的前一节点,next为当前节点的下一节点
        //需要pre和next的目的是让当前节点从pre->head->next1->next2变成pre<-head next1->next2
        //即pre让节点可以反转所指方向,但反转之后如果不用next节点保存next1节点的话,此单链表就此断开了
        //所以需要用到pre和next两个节点
        //1->2->3->4->5
        //1<-2<-3 4->5
        while(head!=null){
           next=head.next;
           head.next=pre;
           pre=head;
           head=next;
         }
         return pre;
     }
 }

JZ-17 树的子结构
在这里插入图片描述

public class Solution {
    public static boolean HasSubtree(TreeNode root1, TreeNode root2) {
        boolean result = false;
        //当Tree1和Tree2都不为零的时候,才进行比较。否则直接返回false
        if (root2 != null && root1 != null) {
            //如果找到了对应Tree2的根节点的点
            if(root1.val == root2.val){
                //以这个根节点为为起点判断是否包含Tree2 根节点相同,继续判断
                result = doesTree1HaveTree2(root1,root2);
            }
            //如果找不到,那么就再去root的左儿子当作起点,去判断时候包含Tree2
            if (!result) {
                result = HasSubtree(root1.left,root2);
            }
             
            //如果还找不到,那么就再去root的右儿子当作起点,去判断时候包含Tree2
            if (!result) {
                result = HasSubtree(root1.right,root2);
               }
            }
            //返回结果
        return result;
    }
 
    public static boolean doesTree1HaveTree2(TreeNode node1, TreeNode node2) {
        //如果Tree2已经遍历完了都能对应的上,返回true
        if (node2 == null) {
            return true;
        }
        //如果Tree2还没有遍历完,Tree1却遍历完了。返回false
        if (node1 == null) {
            return false;
        }
        //如果其中有一个点没有对应上,返回false
        if (node1.val != node2.val) {  
                return false;
        }
         
        //如果根节点对应的上,那么就分别去子节点里面匹配
        return doesTree1HaveTree2(node1.left,node2.left) && doesTree1HaveTree2(node1.right,node2.right);
    }

JZ18-二叉树的镜像
在这里插入图片描述

public class Solution{
 public void Mirror(TreeNode root){
    if(root=null){
       return ;
     }
     TreeNode tmp=root.left;//先把树的左子树赋值给tmp 现在左孩子就是为空
     root.left=root.right;//然后把右孩子赋值过去 变成左子树 
     root.right=tmp;//然后把最初的左子树赋值到右孩子
     Mirror(root.left);//然后对左孩子作为根节点进行用相同的方法交换
     Mirror(root.right)//然后对右孩子作为根节点进行相同的交换镜像
  }
 }

JZ19-顺时针打印矩阵
在这里插入图片描述

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return list;
        }
        int up = 0;//上
        int down = matrix.length-1;//下 
        int left = 0;//左边
        int right = matrix[0].length-1;//右边
        while(true){
            // 最上面一行
            for(int col=left;col<=right;col++){
                list.add(matrix[up][col]);
            }
            // 向下逼近
            up++;
            // 判断是否越界
            if(up > down){
                break;
            }
            // 最右边一行
            for(int row=up;row<=down;row++){
                list.add(matrix[row][right]);
            }
            // 向左逼近
            right--;
            // 判断是否越界
            if(left > right){
                break;
            }
            // 最下面一行
            for(int col=right;col>=left;col--){
                list.add(matrix[down][col]);
            }
            // 向上逼近
            down--;
            // 判断是否越界
            if(up > down){
                break;
            }
            // 最左边一行
            for(int row=down;row>=up;row--){
                list.add(matrix[row][left]);
            }
            // 向右逼近
            left++;
            // 判断是否越界
            if(left > right){
                break;
            }
        }
        return list;
    }
}

JZ20-包含min函数的栈
在这里插入图片描述

import java.util.Stack;

public class Solution {

    private Stack<Integer>stack1;//定义两个栈 stack1保存当前的node数据
    private Stack<Integer>stack2;//stack2用于保存最小元素
    
    public Solution(){
        stack1=new Stack<>();
        stack2=new Stack<>();
    }
    public void push(int node) {
        stack1.push(node);
        if(stack2.isEmpty()||stack2.peek()>node)//去栈顶的值但是不删除值                                                     
            stack2.push(node);//栈2中的栈顶值大于node则把这个较小的值放入到栈2中   因为栈2的目的就是为了存放较小的值
        else
            stack2.push(stack2.peek());//说明当前stack2元素是比较小的,符合要求
                                       //peek取栈顶元素,保留
        
    }
    
    public void pop() {//pop 取栈顶元素,并且删除
        stack1.pop();
        stack2.pop();
        
    }
    
    public int top() {
        return stack1.peek();
    }
    
    public int min() {
        return stack2.peek();//最小的值就是栈2中栈顶最小值。
        
    }
}

在这里插入图片描述

企业真题:
QY1-PDD1

在这里插入图片描述

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));//字符流的读取 控制框的输入
        int n=Integer.parseInt(br.readLine());
        String s=br.readLine();
        String [] strs=s.split(" ");
        
        long[] arr=new long[n];
        for(int i=0;i<n;i++){
            arr[i]=Long.parseLong(strs[i]);
        }
        long res=getAns(arr,n);
        System.out.println(res);
    }
    public static long getAns(long[] arr,int n){ //数组 和数组长度
        for(int i=0;i<3;i++){
            for(int j=i+1;j<n;j++){
                if(arr[i]<arr[j]){
                    long tmp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=tmp;
                }
            }
        }
        long max1=arr[0]*arr[1]*arr[2];
        for(int i=n-1;i>=n-2;i--){
            for(int j=i-1;j>=0;j--){
                if(arr[i]>arr[j]){
                    long tmp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=tmp;
                }
            }
        }
        long max2=arr[0]*arr[n-2]*arr[n-1];
        return Math.max(max1,max2);
    }
}

华为机试-01-字串分割
在这里插入图片描述

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args)throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String input;
        while((input=br.readLine())!=null){
            StringBuilder sb = new StringBuilder(input);
            while(sb.toString().length()>=8){
                System.out.println(sb.toString().substring(0,8));
                sb.delete(0,8);
            }
            if(sb.toString().length()<8 &&sb.toString().length()>0){
                sb.append("00000000");
                System.out.println(sb.toString().substring(0,8));
            }
        }
    }
}

华为机试-02-统计每个月兔子的总数

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main{
   public static void main(String[] args)throws Exception{
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    String line="";
    while((line=br))
    }
 }

华为机试-进制转化
在这里插入图片描述

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int main(){
    string s;
    while(cin>>s){
      int bit=0;
      int ans=0;
      for(int s=s.length()-1;i>1;i--){//从16进制的个位开始,每位都转化成十进制
          if(s[i]>='0'&&s[i]<='9')//数字符的转化
             ans+=(s[i]-'0')*pow(16,bit++);
             else if(s[i]>='A'&&s[i]<='F')//字母字符的转化
                ans+=(s[i]-'A'+10)*pow(16,bit++);
       }
       cout<<ans<<endl;
     }
     return 0;
 }

import java.util.*;
import java.io.*;

public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String input;
        while((input = bf.readLine())!=null){
            String temp = input.substring(2,input.length());
            int sum = 0;
            int length = temp.length();
            for(int i= length-1;i>=0;i--){
                char c = temp.charAt(i);
                int tempNum = (int)c;
                if(tempNum>=65){
                    tempNum = tempNum - 65 + 10;
                }else{
                    tempNum = tempNum - 48;
                }
                sum = sum + (int) Math.pow(16, length-i-1)*tempNum;
            }
            System.out.println(sum);
        }
    }
}

华为机试-质数因子
在这里插入图片描述

#include<stdio.h>
int main(){
   long n,i;
   scanf("%ld",&n);
   i=2;//从2开始
   while(n!=1){
      if(n%i==0){//取余 说明可以整除 每找到一个因数,直到除尽为止,找到的因数一定是质数
          printf("%ld ",i);//打印
          n=n/i;//取整  其实这道题的思路就是i++ 不断去求n是否可以对自增的i进行取余操作 n对i取整 表明n=n/i和之间存在乘积关系
       }
       else
        i++;
    }
 }
import java.io.*;
import java.util.*;
//思路同上
public class Main{
     
    public static void main(String[] args) throws Exception{
        BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        String str="";
        while(null!=(str=bf.readLine())){
            System.out.println(factor(Integer.valueOf(str)));
        }
    }
    public static String factor(int num){
        StringBuffer sb=new StringBuffer();
        for(int i=2;i<Math.sqrt(num);i++){
            if(num%i==0){
                sb.append(i).append(" ");
                num /=i;
                i --;
            }
        }
        return sb.append(num).append(" ").toString();
    }
}

华为机试-统一大写字母
在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main(){
    char a[65536];
    int i,k;
    while(scanf("%s",a)!=EOF){//输入进来的字符  EOF 只要bai文件还有IO的输入,循环就du可以继续zhi进行
        k=0;
        for(int i=0;i<strlen(a);i++){//strlen计算字符串长度
            if(a[i]<=90&&a[i]>=65){// A Z
                k=k+1;
            }
        }
        printf("%d\n",k);
    }
    return 0;
}
import java.io.*;
public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader buff=new BufferedReader(new InputStreamReader(System.in));
        String str="";
        while((str=buff.readLine())!=null){
            String s=str;
            System.out.println(getResult(s));
        }
    }
    
    public static int getResult(String str){
        int x=0;
        for(int i=0;i<str.length();i++){
            if(str.charAt(i)>='A'&&str.charAt(i)<='Z'){//统计个数
                x++;
            }
        }
        return x;
    }
}

华为机试-字符逆序

#include<cstdio>
const int MAX=1e9;
using namespace std;
char str[MAX];
int main(){
    int top=-1;
    char c=getchar();
    while(c!='\n'){
        top++;
        str[top]=c;
        c=getchar();
    }
    while(top!=-1){
        printf("%c",str[top]);
        top--;
    }
    return 0;
}

排序:
冒泡排序

packahe leetcode;
public class bubbleSort{
       public static void bubbsort(int[]arr){
         for(int i=0;i<arr.length-1;i++){//遍历数组
             for(int j=0;j<arr.length-i-1;j++){//内循环
                if(arr[j]<arr[j+1]){//相邻两个之间比较大小,然后交换值。
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                 }
              }
          }
        }
        public static void main(String[] args){
           int[] arr={9,6,7,8,1,3,5,2,0};
           bubbsort(arr);
           for(int i:arr){
               System.out.println(i+"\t");
            }
         }
}

堆排序

package leetcode
public class HeapSort{
    public static void main(String[] args){
       int []arr={16,7,3,20,17,8};
       heapSort(arr);
       for(int i:arr){
           System.out.println(i+"\t");
        }
     }
     private static void heapSort(int[] arr){
         for(int i=(arr.length-1)/2;i>=0;i--){
               adjustHeadp(arr,i,arr.length);
          }
          //调整堆结构+交换堆顶元素与末尾元素
          for(int i=arr.length-1;i>0;i--){
             //将堆顶元素与末尾元素交换
             int temp=arr[i];
             arr[i]=arr[0];
             arr[0]=temp;
             //重新对堆进行调整
             adjustHeap(arr,0,i);
           }
     }
     private static void adjustHeap(int[]arr,int parent,int length){
         //将temp作为父节点
         int temp=arr[parent];
         //左孩子
         int lChild=2*parent+1;
         while(lChild<length){
            //右孩子
            int rChild=lChild+1;
            if(rChild<length&&arr[lChild]<arr[rChild]){
              lChild++;
             }
             //如果父节点的值大于孩子的值,直接结束
             if(temp>=arr[lChild]){
                break;
             }
             //孩子节点赋值给父节点
             arr[parent]=arr[lChild];
             //选取左孩子节点,继续向下筛选
             parent=lChild;
             lChild=2*lChild+1;
          }
          arr[parent]=temp;
      }
 }
  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值