缺失的正整数
/**
* 0~n-1中缺失的数字
*/
public class MissingNum {
public int missingNumber(int[] nums) {
int i = 0;
int j = nums.length - 1;
while (i < j) {
int m = i + ((j - i) >> 2);
if (nums[m] == m) i = m + 1;
else j = m - 1;
}
return nums[i] == i ? nums[i] + 1 : nums[i] - 1;
}
public static void main(String[] args) {
int[] arr = {0, 1, 2, 3, 4, 5, 6, 7, 9};
MissingNum missingNum = new MissingNum();
System.out.println(missingNum.missingNumber(arr));
}
}
数组中重复的数字
//leetcode 指 Offer 03. 数组中重复的数字
public int findRepeatNumber(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<>();
int res = nums[0];
for (int num : nums) {
if (map.get(num) == null) {
map.put(num, 1);
} else {
res = num;
break;
}
}
return res;
}
盛水最多的容器
//leetcode-11 盛最多水的容器
public int maxArea(int[] height) {
int left = 0;
int right = height.length - 1;
int maxArea = 0;
/* while (left < right) {
int width = right - left;
int deep = Math.min(height[left], height[right]);
maxArea = Math.max(maxArea, width*deep);
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return maxArea;*/
while (left < right) {
maxArea = height[left] < height[right] ?
Math.max(maxArea, (right - left) * height[left++]) :
Math.max(maxArea, (right - left) * height[right--]);
}
return maxArea;
}
二分查找
//二分查找:初始值left=0,right=length-1,搜索闭区间[left,right]; while循环条件left<=right;
public static int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
}
}
//return left;
return nums[left] == target ? left : -1;
}
//左边界查找:
public static int leftBoundarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
//return left;
if (nums.length == left) {
return -1;
}
return nums[left] == target ? left : -1;
}
//右边界查找:
public static int rightBoundarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
left = mid + 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
//return left - 1;
if (left == 0) {
return -1;
}
return nums[left - 1] == target ? left - 1 : -1;
}
合并两个有序链表
//合并两个有序链表
public static ListNode mergeTwoLists1(ListNode l1, ListNode l2) {
ListNode res = new ListNode(0);
ListNode head = res;//指向头结点的引用
while (l1 != null && l2 != null) {
if (l1.value < l2.value) {
res.next = l1;
l1 = l1.next;
} else {
res.next = l2;
l2 = l2.next;
}
res = res.next;
}
if (l2 == null) {
res.next = l1;
} else {
res.next = l2;
}
return head.next;
}
找到两个单链表相交的起始结点(判断链表是否相交)
//找到两个单链表相交的起始结点(判断链表是否相交)
//走到尽头见不到你,于是走过你来时的路,等到相遇时才发现,你也走过我来时的路
//我先走我的路,再走你的路,你先走你的路,再走我的路,这样咱俩走的路程就一样了,速度一样,那么肯定在咱俩两条路的交叉口相遇,并一起走向终点。这思路,给跪了!
public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode A = headA;
ListNode B = headB;
// 直到两人相遇
while (A != B) {
if (A != null) {
// 如果A没走到尽头就一直走下去
A = A.next;
} else {
// 直到尽头也没遇见B,所以去往B走过的路
A = headB;
}
if (B != null) {
B = B.next;
} else {
B = headA;
}
}
// 返回A\B第一次相遇的地方
return B;
}
求单链表是否有环(快、慢指针(龟兔赛跑思想,如果出现环形,那么必然相遇),快指针每次移动2步,慢指针每次移动一步
//求单链表是否有环(快、慢指针(龟兔赛跑思想,如果出现环形,那么必然相遇),快指针每次移动2步,慢指针每次移动一步
public static boolean hasCycle(ListNode head) {
if(head == null || head.next == null){
return false;
}
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast){
if (fast == null||fast.next == null){
return false;
}
slow = slow.next;
fast =fast.next.next;
}
//哈希表方案:每次遍历到一个节点时,判断该节点此前是否被访问过。
/* Set<ListNode> seen = new HashSet<>();
while (head!=null){
if (!seen.add(head)){
return true;
}
head = head.next;
}
return false;*/
return true;
}