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);
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章