LeetCode前置课-1-数组,链表,队列,栈

1、数组
二维数组变稀疏数组:


    //1、数组-》稀疏数组
    public static void xishuArray() {
        int array[][] = new int[11][11];
        array[1][2] =1;
        array[1][5] =2;
        array[3][7] =1;
        array[7][9] =1;
        System.out.println("数组:");
        for(int i =0; i<array.length; i++){
            for(int j =0; j<array[1].length;j++){
                System.out.print(array[i][j]+" ");
            }
            System.out.println("");
        }
        int sum = 0;
        for(int i =0; i<array.length; i++){
            for(int j =0; j<array[1].length;j++){
                if(0!=array[i][j]){
                    sum++;
                }
            }
        }

        int sparesArray[][] = new int[sum+1][3];
        sparesArray[0][0] = array.length;
        sparesArray[0][1] =  array[0].length;
        sparesArray[0][2] = sum;

        int count =0;
        for(int i =0; i<array.length; i++){
            for(int j =0; j<array[1].length;j++){
                if(0!=array[i][j]){
                    count++;
                    sparesArray[count][0]=i;
                    sparesArray[count][1]=j;
                    sparesArray[count][2]=array[i][j];
                }
            }
        }

        System.out.println("稀疏数组:");
        for(int i =0; i<sparesArray.length; i++){
            for(int j =0; j<sparesArray[1].length;j++){
                System.out.print(sparesArray[i][j]+" ");
            }
            System.out.println("");
        }

    }

2、数组实现一个顺序队列:

public class ArrayQueue {

    private int rear;//指向队列尾部
    private int front ;//指向队列头部
    private int maxSize ;
    private int[] queue ;

    public ArrayQueue (int ArraymaxSize){
        rear = -1;
        front= -1;
        maxSize=ArraymaxSize;
        queue=new int[maxSize];
    }

    public boolean isFull(){//队列是否已满
        return rear==maxSize-1;
    }
    public  boolean isEmpty(){//队列是否为空
        return rear==front;
    }

    public void addToQueue(int n){
        if(isFull()){
            return;
        }
        rear=rear+1;
        queue[rear]=n;
    }
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("空");
        }else{
            front=front+1;
            return queue[front];
        }
    }
    public void showQueue(){//显示,不是取出
        if(isEmpty()){
            System.out.println("空");
            return;
        }
        for(int i : queue){
            System.out.print(i+" ");
        }
    }
    public int getQueueHead(){
        if(isEmpty()){
            throw new RuntimeException("kong");
        }
        return queue[front+1];//front表示头
    }


}

3、数组实现环状队列  (FIFO)

/**
 * Created by qililong on 2020/6/19.
 */
public class CircelQueue {
    private int rear;//表示最后一个元素的后一个位置,默认空出一位
    private int front;//指向队列的第一个元素,初始值0
    private int maxSize;//最大容量
    private int[] arr;//存放数据

    public  CircelQueue(int arrMaxSize){
        maxSize=arrMaxSize;
        arr=new int[maxSize];
    }

    //表示是否已满,如果front不动,rear到了最后一个,判断是否已满:取余数
    public boolean isFull(){
        return (rear+1)%maxSize==front;
    }
    public boolean isEmpty(){
        return  rear==front;
    }
    //添加数据到队列
    public void addToQueue(int n){
        if (isFull()){
            System.out.println("满了");
            return;
        }
        arr[rear]=n;//保存
        rear=(rear+1)%maxSize;//到数组结尾之后可以取模从头开始
    }
    //取出队列
    public int getQueue(){
        if(isEmpty()){
            throw new RuntimeException("空异常");
        }
        int val = arr[front];
        front=(front+1)%maxSize;
        return val;
    }
    //显示队列的所有数据
    public void showQueue(){
        if (isEmpty()){
            System.out.println("kong");
            return;
        }
        for(int i=front;i<front+size();i++){
            System.out.println(arr[i]);
        }
    }
    //计算列表中有多少数据
    private int size(){
        return (rear+maxSize-front)%maxSize;
    }
    //获取列表头
    public int headQueue(){
        if (isEmpty()){
            throw  new RuntimeException("kong");
        }
        return arr[front];
    }
}

3、链表:分带头结点的链表和不带头结点的链表

单向链表包含data域和next域

实现一个链表:


/**
 * Created by qililong on 2020/6/19.
 */
public class LinkList {
    //定义头节点,不可动
    public Node head =  new Node(0);
    //应该独立定义一个node类文件

    //1新建链表
    public   Node array(int[] a){
//        int[] a = {1,2,3,4,5,6};
        Node temp = head;
        for(int i=0; i<a.length; i++){
            Node node = new Node(a[i]);
            temp.next=node;
            temp=temp.next;
        }
        return head;
    }
    //2、插入一个节点
    public void addByOrder(Node node){
        Node temp = head;
        boolean flag = false;//新加入的节点是否存在
        while (true){
            if(temp.next==null){//找到了结尾
                break;
            }
            if(temp.next.no>node.no){//找到位置
                break;
            }else if(temp.next.no == node.no){//表示已存在
                flag = true;
            }
            temp=temp.next;
        }
        if(flag){
            throw new RuntimeException("已存在");
        }else {//插入
            node.next=temp.next;
            temp.next=node;
        }
    }
    //3、删除节点->需要找到要删除节点的前一个节点
    public void del(int no){
        Node temp =  head;
        boolean flag = false;//标识是否是找到节点退出的循环
        while(true){
            if(temp.next==null){
                break;//走到尽头
            }
            if(temp.next.no==no){//找到待删除节点的前一个节点
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if(flag){
            temp.next=temp.next.next;
        }else{
            throw  new RuntimeException("未找到要删除的的节点");
        }
    }
    //4、显示链表:
    public void showLikeList(){
        Node temp = head;
        while (true){
            if(temp.next==null){
                break;
            }
            System.out.println(temp);
            temp=temp.next;
        }
    }
    //5、计算链表有效节点个数
    public static int getLinkListLength(Node head){
        if(null == head){
            throw new RuntimeException("链表为空");
        }
        int count = 0;
        Node cur = head.next;//头结点未参与统计
        while (cur!=null){
            count++;
            cur = cur.next;//遍历
        }
        return count;
    }
    //6,计算倒数第k个节点
    public static  Node findLastIndexNode(Node headNode, int k){
        int length = getLinkListLength(headNode);
        if(k<=0|| k>length){
            return null;
        }
        int num = length-k;
        Node temp = headNode.next;
        while (num>0){
            num--;
            temp=temp.next;
        }
        return temp;
    }
    //7、单链表反转
    public static  void  reversetList(Node headNode ){
        //链表为空或者只有一个节点不必反转'
        if(null == headNode || headNode.next==null || headNode.next.next==null){
            return;
        }
        Node cur = headNode.next;//协助遍历原链表
        Node next = null;//指向当前节点的下一个节点
        Node reversethead= new Node(0);
        while (cur!=null){
            next = cur.next;//暂存原链表剩下的节点
            cur.next=reversethead.next;//将当前节点next域指向前一个节点
            reversethead.next= cur;//reversethead.next移动一个位置,与上一句合到一起就是cur.next=cur
            cur=next;//原链表cur节点向后移动
        }
        //头结点连接到新链表
        headNode.next= reversethead.next;
    }
    //8单链表倒序输出(也可利用实现反转)
    public static void reversetShowList(Node head){
        if(null == head || head.next==null){
            return;
        }
        Stack myStack = new Stack();
        Node cur = head.next;
        while (cur!=null){
            myStack.push(cur);
            cur=cur.next;
        }
        while (!myStack.isEmpty()){
            Node node = (Node) myStack.pop();
            System.out.println(node);
        }
    }
    //9合并两个有序单链表,合并后依然有序
    public static Node  mergeLinkList(Node head1 , Node head2){
        //递归结束条件
        if(head1==null && head2==null){
            return null;
        }
        if(head1==null){
            return head2;
        }
        if(head2==null){
            return head1;
        }
        Node head = null;
        if(head1.no>head2.no){
            head=head2;
            head.next=mergeLinkList(head1, head2.next);
        }else {
            head=head1;
            head.next=mergeLinkList(head1.next, head2);
        }
        return head;
    }
 //10如果两个链表相交,输出交点
    public static Node getMergeNode(LinkList link1,LinkList link2){

        //让长的链表先走,等到和短的链表一样长时依次比较两个链表节点
        int size1 = link1.getLinkListLength(link1.head);
        int size2 = link2.getLinkListLength(link2.head);
        Node cur1 =null;
        Node cur2 =null;
        if(size1>size2){
            cur1=link1.head.next;
            cur2=link2.head.next;
        }else{
            cur1=link2.head.next;
            cur2=link1.head.next;
        }
        int step = Math.abs(size1-size2);
        for( ; step>0; step--){
            cur1=cur1.next;
        }
        while (cur1!=null){
            if(cur1==cur2) return cur1;
            cur1=cur1.next;
            cur2=cur2.next;
        }
        return null;
    }

4、栈后进先出

//新建栈类
     static class ArrayStack{
        private int maxSize;
        private int[] stack;
        private int top=-1;//栈顶

        public  ArrayStack(int size){
            this.maxSize=size;
            stack=new int[size];
        }

        public boolean isFull(){
            return top==maxSize-1;
        }
        public  boolean isEmpty(){
            return top==-1;
        }
        public void addToStack(int m){
            if(isFull())return;
            top++;
            stack[top]=m;
        }
        public int pop(){
            if(isEmpty()){
                throw  new RuntimeException("kong");
            }
            int res = stack[top];
            top--;
            return res;
        }
        public void showList(){
            if(isEmpty()){
                throw  new RuntimeException("kong");
            }
            for(int i=top;i>=0; i-- ){
                System.out.println(stack[i]+"");
            }
        }
    }

5、递归-小球递归走迷宫

//递归实现小球走迷宫
    /**
     *
     * @param map 地图
     * @param i
     * @param j ij起点坐标
     */
    public static  boolean setWay(int[][] map , int i,int j){
        if(map[5][6]==2){
            return true;//表示终点可达
        }else{
            if(map[i][j]==0){//0表示可通行,还未走
                map[i][j]=2;//2表示已走
                if(setWay(map,i+1,j)){
                    return true;
                }else if(setWay(map,i,j+1)){
                    return true;
                }else if(setWay(map, i-1, j)){
                    return true;
                }else if(setWay(map, i, j-1)){
                    return true;
                }
            }else{
                return false;
            }
            return false;
        }
    }

6、八皇后问题:递归+回溯

/**
 * Created by qililong on 2020/6/30.
 * 八皇后问题
 */
public class Queue8 {

    int max= 8 ;//表示有8个皇后
    int arrar[]= new int[max];//表示八皇后在棋盘上的坐标
    static int count = 0;//表示有几种摆法

    //方式第n个皇后,check是递归的,每次递归都for()判断所有皇后因此会回溯
    private void check(int n){
        if(n==max){//表示八个皇后都放置OK了
            print();
            return;//第一种放完后退出第一种递归,进行下一种计算
        }
        //依次放入皇后并判断是否冲突
        //判断当放置第n个皇后到i列时是否冲突,不冲突就放下一个皇后,冲突了就把当前放入的皇后往后方一列试试,直到不冲突,
        // 或者当前皇后放入所有的列都冲突,则for循环会走完退回到上一次递归重新放上一个皇后到后一列
        for(int i=0;i<max;i++){
            arrar[n]=i;
            //判断当放置第n个皇后到i列时是否冲突
            if(judge(n)){//不冲突
                check(n+1);//放置第n+1个
            }
        }
    }
    public boolean judge(int n){
        //判断n皇后和之前所有皇后是否冲突(同一列,或者同一斜线)
        for(int i=0;i<n;i++){
            if(arrar[i]==arrar[n] || Math.abs(n-i)==Math.abs(arrar[n]-arrar[i])){
                return false;
            }
        }
        return true;
    }
    private void print() {
        count++;
        for(int i=0;i<arrar.length;i++){
            System.out.println(arrar[i]+"");
        }
    }

    public static  void  main(String[] args){
        Queue8 queue8 = new Queue8();
        queue8.check(0);
        System.out.println(count);
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值