◼ 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明: 给定的 n 保证是有效的。 要求: 只允许对链表进行一次遍历。
出题人:阿里巴巴出题专家:屹平/阿里云视频云边缘计算高级技术专家
参考答案:
我们可以使用两个指针而不是一个指针。第一个指针从列表的开头向前移动 n+1 步,而第二个指针将从列表的开头出发。现在,这两个指针被 n 个结点分开。我们通过同时移动两个指针向前来保持这个恒定的间隔,直到第一个指针到达最后一个结点。此时第二个指针将指向从最后一个结点数起的第 n 个结点。我们重新链接第二个指针所引用的结点的 next 指针指向该结点的下下个结点。
/**
* Definition for a binary tree node.
**/
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
private class ResultType {
boolean found; // 是否找到
int val; // 节点数目
ResultType(boolean found, int val) {
this.found = found;
this.val = val;
}
}
public int kthSmallest(TreeNode root, int k) {
return kthSmallestHelper(root, k).val;
}
private ResultType kthSmallestHelper(TreeNode root, int k) {
if (root == null) {
return new ResultType(false, 0);
}
ResultType left = kthSmallestHelper(root.left, k);
// 左子树找到,直接返回
if (left.found) {
return new ResultType(true, left.val);
}
// 左子树的节点数目 = K-1,结果为 root 的值
if (k - left.val == 1) {
return new ResultType(true, root.val);
}
// 右子树寻找
ResultType right = kthSmallestHelper(root.right, k - left.val - 1);
if (right.found) {
return new ResultType(true, right.val);
}
// 没找到,返回节点总数
return new ResultType(false, left.val + 1 + right.val);
}
}
// BST is binary search tree
type BST struct {
key, value int
left, right *BST
}
func (bst *BST) setLeft(b *BST) {
bst.left = b
}
func (bst *BST) setRight(b *BST) {
bst.right = b
}
// count 查找bst第k个节点的值,未找到就返回0
func count(bst *BST, k int) int {
if k < 1 {
return 0
}
c := 0
ok, value := countRecursive(bst, &c, k)
if ok {
return value
}
return 0
}
// countRecurisive 对bst使用中序遍历
// 用计数方式控制退出遍历,参数c就是已遍历节点数
func countRecursive(bst *BST, c *int, k int) (bool, int) {
if bst.left != nil {
ok, value := countRecursive(bst.left, c, k)
if ok {
return ok, value
}
}
if *c == k-1 {
return true, bst.value
}
*c++
if bst.right != nil {
ok, value := countRecursive(bst.right, c, k)
if ok {
return ok, value
}
}
return false, 0
}
// 下面是测试代码,覆盖了退化的情况和普通bst
func createBST1() *BST {
b1 := &BST{key: 1, value: 10}
b2 := &BST{key: 2, value: 20}
b3 := &BST{key: 3, value: 30}
b4 := &BST{key: 4, value: 40}
b5 := &BST{key: 5, value: 50}
b6 := &BST{key: 6, value: 60}
b7 := &BST{key: 7, value: 70}
b8 := &BST{key: 8, value: 80}
b9 := &BST{key: 9, value: 90}
b9.setLeft(b8)
b8.setLeft(b7)
b7.setLeft(b6)
b6.setLeft(b5)
b5.setLeft(b4)
b4.setLeft(b3)
b3.setLeft(b2)
b2.setLeft(b1)
return b9
}
func createBST2() *BST {
b1 := &BST{key: 1, value: 10}
b2 := &BST{key: 2, value: 20}
b3 := &BST{key: 3, value: 30}
b4 := &BST{key: 4, value: 40}
b5 := &BST{key: 5, value: 50}
b6 := &BST{key: 6, value: 60}
b7 := &BST{key: 7, value: 70}
b8 := &BST{key: 8, value: 80}
b9 := &BST{key: 9, value: 90}
b1.setRight(b2)
b2.setRight(b3)
b3.setRight(b4)
b4.setRight(b5)
b5.setRight(b6)
b6.setRight(b7)
b7.setRight(b8)
b8.setRight(b9)
return b1
}
func createBST3() *BST {
b1 := &BST{key: 1, value: 10}
b2 := &BST{key: 2, value: 20}
b3 := &BST{key: 3, value: 30}
b4 := &BST{key: 4, value: 40}
b5 := &BST{key: 5, value: 50}
b6 := &BST{key: 6, value: 60}
b7 := &BST{key: 7, value: 70}
b8 := &BST{key: 8, value: 80}
b9 := &BST{key: 9, value: 90}
b5.setLeft(b3)
b5.setRight(b7)
b3.setLeft(b2)
b3.setRight(b4)
b2.setLeft(b1)
b7.setLeft(b6)
b7.setRight(b8)
b8.setRight(b9)
return b5
}
func createBST4() *BST {
b := &BST{key: 1, value: 10}
last := b
for i := 2; i < 100000; i++ {
n := &BST{key: i, value: i * 10}
last.setRight(n)
last = n
}
return b
}
func createBST5() *BST {
b := &BST{key: 99999, value: 999990}
last := b
for i := 99998; i > 0; i-- {
n := &BST{key: i, value: i * 10}
last.setLeft(n)
last = n
}
return b
}
func createBST6() *BST {
b := &BST{key: 50000, value: 500000}
last := b
for i := 49999; i > 0; i-- {
n := &BST{key: i, value: i * 10}
last.setLeft(n)
last = n
}
last = b
for i := 50001; i < 100000; i++ {
n := &BST{key: i, value: i * 10}
last.setRight(n)
last = n
}
return b
}
func TestK(t *testing.T) {
bst1 := createBST1()
bst2 := createBST2()
bst3 := createBST3()
bst4 := createBST4()
check(t, bst1, 1, 10)
check(t, bst1, 2, 20)
check(t, bst1, 3, 30)
check(t, bst1, 4, 40)
check(t, bst1, 5, 50)
check(t, bst1, 6, 60)
check(t, bst1, 7, 70)
check(t, bst1, 8, 80)
check(t, bst1, 9, 90)
check(t, bst2, 1, 10)
check(t, bst2, 2, 20)
check(t, bst2, 3, 30)
check(t, bst2, 4, 40)
check(t, bst2, 5, 50)
check(t, bst2, 6, 60)
check(t, bst2, 7, 70)
check(t, bst2, 8, 80)
check(t, bst2, 9, 90)
check(t, bst3, 1, 10)
check(t, bst3, 2, 20)
check(t, bst3, 3, 30)
check(t, bst3, 4, 40)
check(t, bst3, 5, 50)
check(t, bst3, 6, 60)
check(t, bst3, 7, 70)
check(t, bst3, 8, 80)
check(t, bst3, 9, 90)
check(t, bst4, 1, 10)
check(t, bst4, 2, 20)
check(t, bst4, 3, 30)
check(t, bst4, 4, 40)
check(t, bst4, 5, 50)
check(t, bst4, 6, 60)
check(t, bst4, 7, 70)
check(t, bst4, 8, 80)
check(t, bst4, 9, 90)
check(t, bst4, 99991, 999910)
check(t, bst4, 99992, 999920)
check(t, bst4, 99993, 999930)
check(t, bst4, 99994, 999940)
check(t, bst4, 99995, 999950)
check(t, bst4, 99996, 999960)
check(t, bst4, 99997, 999970)
check(t, bst4, 99998, 999980)
check(t, bst4, 99999, 999990)
}
func check(t *testing.T, b *BST, k, value int) {
t.Helper()
checkCall(t, b, k, value, count)
// 此处可添加其他解法的实现
}
func checkCall(t *testing.T, b *BST, k, value int, find func(bst *BST, kth int) int) {
t.Helper()
got := find(b, k)
if got != value {
t.Fatalf("want:%d, got:%d", value, got)
}
}
class LRUCache(object):
def __init__(self, capacity):
"""
:type capacity: int
"""
self.cache = {}
self.keys = []
self.capacity = capacity
def visit_key(self, key):
if key in self.keys:
self.keys.remove(key)
self.keys.append(key)
def elim_key(self):
key = self.keys[0]
self.keys = self.keys[1:]
del self.cache[key]
def get(self, key):
"""
:type key: int
:rtype: int
"""
if not key in self.cache:
return -1
self.visit_key(key)
return self.cache[key]
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: void
"""
if not key in self.cache:
if len(self.keys) == self.capacity:
self.elim_key()
self.cache[key] = value
self.visit_key(key)
def main():
s =
[["put","put","get","put","get","put","get","get","get"],[[1,1],[2,2],[1],[3,3],[2],[
4,4],[1],[3],[4]]]
obj = LRUCache(2)
l=[]
for i,c in enumerate(s[0]):
if(c == "get"):
l.append(obj.get(s[1][i][0]))
else:
obj.put(s[1][i][0], s[1][i][1])
print(l)
if __name__ == "__main__":
main()
class LRUCache{
public:
LRUCache(int capacity) {
cap = capacity;
}
int get(int key) {
auto it = m.find(key);
if (it == m.end()) return -1;
l.splice(l.begin(), l, it->second);
return it->second->second;
}
void set(int key, int value) {
auto it = m.find(key);
if (it != m.end()) l.erase(it->second);
l.push_front(make_pair(key, value));
m[key] = l.begin();
if (m.size() > cap) {
int k = l.rbegin()->first;
l.pop_back();
m.erase(k);
}
}
}
public ListNode removeNthFromEnd(ListNode head, int n)
{
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode first = dummy;
ListNode second = dummy;
// Advances first pointer so that the gap between first
and second is n nodes apart
for (int i = 1; i <= n + 1; i++) {
first = first.next;
}
// Move first to the end, maintaining the gap
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
public int[] twoSum(int[] nums, int target) {
if(nums==null || nums.length<2)
return new int[]{0,0};
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0; i<nums.length; i++){
if(map.containsKey(nums[i])){
return new int[]{map.get(nums[i]), i};
}else{
map.put(target-nums[i], i);
}
}
return new int[]{0,0};
}