编写一个程序,找到两个单链表相交的起始节点。
思路:
求出每个链表的长度,长的那个先走几步,然后一起走,遇到相等就停步
class Solution(object):
def getIntersectionNode(self, headA, headB):
node = headA
len_a = 0
len_b = 0
while node:
node = node.next
len_a +=1
node = headB
while node:
node = node.next
len_b +=1
gap = abs(len_a-len_b)
if len_a > len_b:
while gap !=0:
headA = headA.next
gap-=1
if len_b > len_a:
while gap !=0:
headB = headB.next
gap-=1
while headA != headB:
headA = headA.next
headB = headB.next
return headA
简化版:
调试了好久,还是要想清楚阿…
class Solution(object):
@classmethod
def getIntersectionNode(self, headA, headB):
if(headA == None or headB == None):
return None
nodeA = headA
nodeB = headB
len_a, len_b = 0, 0
while nodeA != None or nodeB != None:
nodeA = nodeA if nodeA == None else nodeA.next
nodeB = nodeB if nodeB == None else nodeB.next
len_a = len_a + 1 if nodeA != None else len_a
len_b = len_b + 1 if nodeB != None else len_b
gap = abs(len_a-len_b)
while gap > 0:
headA = headA if len_a < len_b else headA.next
headB = headB if len_a > len_b else headB.next
gap -= 1
while headA != headB:
headA = headA.next
headB = headB.next
return headA
讨论区:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
/**
定义两个指针, 第一轮让两个到达末尾的节点指向另一个链表的头部, 最后如果相遇则为交点(在第一轮移动中恰好抹除了长度差)
两个指针等于移动了相同的距离, 有交点就返回, 无交点就是各走了两条指针的长度
**/
if(headA == null || headB == null) return null;
ListNode pA = headA, pB = headB;
// 在这里第一轮体现在pA和pB第一次到达尾部会移向另一链表的表头, 而第二轮体现在如果pA或pB相交就返回交点, 不相交最后就是null==null
while(pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}
给定一个大小为n的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
class Solution(object):
def majorityElement(self, nums):
#摩尔投票算法 不是很懂
ans = nums[0]
count = 0
for num in nums[1:]:
if num == ans:
count +=1
elif count > 0:
count -=1
else:
ans = num
return ans
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1:
输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
备注:
递归必须使用记忆化搜索,不然会超时
class Solution(object):
map = []
def rob(self, nums):
self.map = [-1 for x in range(len(nums))]
return self.robCore(nums,0)
def robCore(self,nums,k):
if k>=len(nums):
return 0
if self.map[k] != -1:
return self.map[k]
#当只剩两个元素时,可以直接求解
n = len(nums[k:])
if n<=2:
return max(nums[k:])
a = max(self.robCore(nums,k+2),self.robCore(nums,k+1))
b = self.robCore(nums,k+2)+nums[k]
self.map[k] = max(a,b)
return self.map[k]
讨论区动态规划解法:
public int rob2(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
// memo[i] 表示考虑抢劫 nums[i...n-1] 所能获得最大收益(不是说一定从 i 开始抢劫)
int[] memo = new int[n];
// 先考虑最简单的情况
memo[n - 1] = nums[n - 1];
for (int i = n - 2; i >= 0; i--) {
// memo[i] 的取值在考虑抢劫 i 号房子和不考虑抢劫之间取最大值
memo[i] = Math.max(nums[i] + (i + 2 >= n ? 0 : memo[i + 2]), nums[i + 1] + (i + 3 >= n ? 0 : memo[i + 3]));
}
return memo[0];
}
public int rob3(int[] nums) {
int n = nums.length;
if (n <= 1) return n == 0 ? 0 : nums[0];
int[] memo = new int[n];
memo[0] = nums[0];
memo[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < n; i++)
memo[i] = Math.max(memo[i - 1], nums[i] + memo[i - 2]);
return memo[n - 1];
}
给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
思路:
遇到1时将所有可达的为1的点合并
class Solution(object):
dx = [1,0,-1,0]
dy = [0,-1,0,1]
def numIslands(self, grid):
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1':
self.dfs(grid,i,j)
ans +=1
return ans
def dfs(self,grid,i,j):
grid[i][j] = '.'
for k in range(4):
m = i+self.dx[k]
n = j+self.dy[k]
if m>-1 and m<len(grid) and n >-1 and n<len(grid[0]) and grid[m][n] == '1':
self.dfs(grid,m,n)
return
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
迭代式:
class Solution(object):
def reverseList(self, head):
pre,cur = None,head
while cur != None:
next = cur.next
cur.next = pre
pre = cur
cur = next
return pre
递归:
class Solution(object):
def reverseList(self, head):
if not head or not head.next:
return head
new_head = self.reverseList(head.next)
head.next.next = head
head.next = None
return new_head
讨论区:
class Solution(object):
def reverseList(self, head):
pre,cur = None,head
while cur:
pre,pre.next,cur = cur, pre, cur.next
return pre