回溯和链表操作
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;
}
}