2021-05-30

回溯和链表操作

1.leetcode 92链表逆置

首先是整条链表的逆置
在这里插入图片描述

public ListNode reverseList(ListNode head) {
		//使用pre指向cur的前边
        //next指向cur的后边
        ListNode cur = head;
        ListNode pre = null;
        while(cur != null)
        {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
//        return head;
        return pre;//cur指向null时pre指向新链表的头
    }

在这里插入图片描述

在这里插入图片描述

class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
            //不明觉厉的dummyHead 防止head也要修改
        ListNode dummyHead  =  new ListNode(-1);
        dummyHead.next = head;
        
        ListNode pre = dummyHead;
        for (int i = 0; i < left-1; i++) { //dummyHead在Head前 Head下标为1 则从0到left-1 动left次 到rightNode那个节点的前一个
            pre = pre.next;//保留pre指向逆置区域前一个节点不变
        }
        ListNode cur = pre.next;
        ListNode next = null;
        // while(cur!=next)
        for(int i = 0 ; i < right -  left ;i++)//根据left和right的距离使得
        {
            next = cur.next;//next指向cur.next 保存要逆置的节点的信息
            cur.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }

        return dummyHead.next;
    }
}

2.leetcode 1863. 找出所有子集的异或总和再求和

回溯

class Solution {
   int res = 0;
   public int subsetXORSum(int[] nums) {
       if(nums.length == 1) return nums[0];
       dfs(0,0,nums);
       return res;
   }
    public void dfs(int val,int idx,int[] nums)
   {
       if(idx == nums.length)
       {
           // res += res;
           res += val;
           return;
       }
       dfs(val ^ nums[idx],idx+1,nums);//计算当前数进入异或的集合
       dfs(val ,idx+1,nums);//不计算当前数进入异或的集合
   }
}

https://blog.csdn.net/m0_46549425/article/details/108025133
DFS入门

3.leetcode11. 盛最多水的容器

此题比较简单 很容易想出两两相乘得出面积最终得到最大值得暴力解法在这里插入图片描述
可惜O(N^2)时间复杂度超出
双指针法 首先从数组两头最大距离开始

 public int maxArea2(int[] height) {
       int i = 0 , j = height.length-1;//j = height;
       int max = 0 ;
       while (i!=j)
       {
           int t = (j-i) * Math.min(height[i],height[j]);
           if(t > max) max = t;

           if(height[i+1] >= height[j-1])
           {
               j--;
           }else {
               i++;
           }
       }
       return max;
    }

3.leetcode88. 合并两个有序数组

归并排序 两个数组已经有序
在这里插入图片描述
在这里插入图片描述
原来是help[i++] = nums1[p1] < nums2[p2] ? nums1[p1++] :nums2[p2++]; 这里写错了

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
                int[] help = new int[m+n];
        int p1 = 0,p2 = 0;
        int i = 0;
        while(p1 < m && p2 < n)
        {
            help[i++] =  nums1[p1] < nums2[p2] ? nums1[p1++] :nums2[p2++];
        }
        while (p1  < m)
        {
            help[i++] = nums1[p1++];
        }
        while (p2  < n)
        {
            help[i++] = nums2[p2++];
        }
        // nums1 = help;
        for( i = 0 ; i < m+n ; i++)
        {
            nums1[i] = help[i];
        }
    
    }
}

4.leetcode69. x 的平方根

二分法 在数字的范围内进行

    public int mySqrt(int x) {
        int L = 0, R = x; int ans  = -1;
        while (L <= R)
        {
//            int mid = L + ((R - L)) >> 1;  >>的优先级小于+
            int mid = L + ((R - L) >> 1);
            long square =  mid * mid;
            if(square <= x) {
                ans = mid;
        //平方小于x时 可能此值位于新mid的左边 所以需要记录此时mid位置作为ans
        //平方根是小数 x< 平方根 <x+1 当在新mid左边时 在此时的L R之间的值都小于x 不断求mid 最终L <= R 越界 ans在此处记录即可得到平方根的整数部分
                L = mid + 1;
            }else {//mid只可能在mid的左边区域 mid不可能为可能值
                R =mid - 1 ;
            }
        }
        return ans;
    }
}

5.leetcode374. 猜数字大小

 public int guessNumber(int n) {
        int l = 1; int r = n;
//        while (l < r)
        while (l <= r)
        {
            int mid = l + ((r - l) >> 1);
            if(guess(mid) < 0)
            {
                r = mid - 1;
            }else if(guess(mid) > 0)
            {
                l = mid + 1;
            }else {
                return mid;
            }
        }
        return 0;
    }

6.leetcode378有序矩阵中第 K ⼩的元素

class Solution {
 public int kthSmallest(int[][] matrix, int k) {
     int n = matrix.length;
     int l = matrix[0][0];
     int r = matrix[n - 1][n - 1];
     while (l < r) {
         int mid = l + ((r - l) >> 1);
         if (check(matrix,mid,k,n))//如果大于此值的数小于k
         {
             r = mid ;
         }else {
             l = mid + 1;
         }
     }
     return l;
 }
 public boolean check(int[][] matrix , int mid,int k , int n)
 {

     int i = n - 1;
     int j = 0;
     int num = 0;
     while (i >= 0 && j < n) {
         if (matrix[i][j] <= mid) {
             num += i + 1;
             j++;
         } else {
             i--;
         }
     }
     return num >= k;

 }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值